Mappingthe Commodore 128
Mappingthe Commodore 128
THE
COMMODORE
128
Ottis R. Cowper
COMPUTE! Publications,Inc
Part or ABC Consumer Magazines. Inc.
One of the ABC Publishing Companies
10 9 8 7 6 5 4 3 2 1
ISBN 0-87455-060-2
The author and publisher have made every effort in the preparation of this book to insure the ac-
curacy of the programs and information However, the information and programs in this book are
sold without warranty, either express or implied. Neither the author nor COMPUTE! Publications,
Inc. will be liable for any damages caused or alleged to be caused direct!)', indirectly, incidentally,
or consequentially by the programs or information in this book.
The opinions expressed in this book are solely those of the author and are not necessarily those of
COMPUTE! Publications, Inc.
COMPUTE! Publications, Inc., Post Office Boy 5406, Greensboro, NC 27403, (919)
275-9809, is part of ABC Consumer Magazines, Inc., one of the ABC Publishing Com-
panies, and is not associated with any manufacturer of personal computers. Commo-
dore 64 and Commodore 128 are trademarks of Commodore Electronics Limited,
Contents
Preface v
Introduction vii
1. Memory Organization 1
2. Common Working Storage Area 13
3. Bank 0 Working Storage Area 115
4. RAM Usage 181
5. BASIC ROM 195
6. Machine Language Monitor ROM 241
7. Screen Editor ROM 267
8. I/O Chip Registers, Color RAM, and Character ROM 331
9. Kernal ROM 509
Appendices 617
A. Interrupts/Todrf Heimarck 619
B. Bugs and Quirks in 128 ROM 625
C. Character, Screen, and Keyboard Codes 629
D. Musical Note Frequencies 645
E. 64/128 Memory Map Cross Reference 649
P. BASIC Keyword Index 657
G. Index of Locations and Routines 663
Preface
The random access memory (RAM), read-only memory (ROM),
and interface hardware chips in your Commodore 128 are like
postal stations with hundreds of thousands of mailboxes, each
of which can hold a single character, or byte of information.
This book is a map of all of those memory locations, but it's
more than just a list of addresses. It's also a thorough discus-
sion of how the locations are used by the computer, and, more
importantly, how you can take advantage of this information
to write more powerful programs.
Why a mapping book? The 128's BASIC is the most
powerful version yet in a Commodore computer. It could be
argued that there's little need to get "under the hood" of the
128, since most of the functions that required lots of PEEKs
and POKEs and an intimate understanding of internal hard-
ware functioning in earlier models like the Commodore 64 can
now be handled by simple BASIC statements on the 128.
While it may be true that the 128's advanced BASIC makes
programming easier, complete control over all the computer's
features belongs only to those who understand the secrets of
how the system operates. The purpose of this book is to un-
lock those secrets. The information is valuable for both begin-
ning BASIC and advanced machine language programmers.
The standard features provided by the 128 are often plain
vanilla, giving only the barest hint of the full capabilities of
the computer. Would you like to set up a Dvorak keyboard
that will work with almost any program? See the discussion of
the keyboard table pointers in Chapter 2. How about an 80-
column X 50-line screen display on your RGB monitor? The
explanation of the VDC chip registers in Chapter 8 explains
the necessary steps. Do you want to learn how the computer
sends data over the serial bus? The process is described in
Chapter 9. In fact, you'll find here the answers to most of your
questions about the 128. And these answers are written in un-
derstandable, clear prose.
This book is the result of painstaking disassembly and de-
ciphering of the Commodore 128 ROMs—a task that required
gallons of midnight oil. Commodore's BASIC and operating
system are now nearly ten years old. The ROM routines have
many twists and turns where various Commodore program-
mers have made additions and enhancements along the way.
Although the 128 is internally quite different from the Com-
modore 64, there are similarities. As a result, several previous
COMPUTE! books for the 64 provided invaluable assistance in
attempts to understand some of the intricacies. I'm particularly
indebted to Sheldon Leemon for Mapping the Commodore 64,
and to Dan Heeb for his two volumes of Commodore 64 and
V1C-20 Tool Kit: BASIC and Kernal.
Every effort has been made to insure that the information
provided here is accurate, but in a project of this size and
scope it is inevitable that some errors will creep in. Please
send any corrections you may discover to the attention of the
Book Editor at COMPUTE! Publications in Greensboro. You
can also send electronic mail messages concerning this book to
CompuServe user ID 73317,1143 or to BIX (Byte Information
Exchange) user name ottis.
I'd like to salute my wife Gail for moral and logistical
support far above and beyond the call of duty. I'd also like to
thank the COMPUTE! staff for patience shown when this
project dragged on months longer than anticipated. Finally, I'd
like to dedicate this book to George and George, departing
and arriving as the work took shape.
VI
Introduction
This memory map is a guide to the way a Commodore 128 in
128 mode uses and manipulates its RAM and ROM. No at-
tempt is made here to provide detailed coverage of the 128's
64 mode. A Commodore 128 in 64 mode doesn't just emulate
a Commodore 64; for all practical purposes it is a 64, with
completely separate Kernal and BASIC ROM. The memory
map of the Commodore 64 mode (and its BASIC 2.0) is cov-
ered in complete detail in COMPUTERS Mapping the Commo-
dore 64. However, Appendix E discusses those 128 features
available in 64 mode, and provides a cross reference of impor-
tant memory locations for 64 and 128 modes—information
that will be useful in translating Commodore 64 machine lan-
guage routines for use in 128 mode.
Nor does this book make any attempt to map the way the
128's CP/M mode uses memory. CP/M is a large and com-
plex operating system, and a CP/M mode memory map would
easily fill another entire volume. Moreover, the major portion
of CP/M is loaded from disk instead of being permanently
stored in ROM. As a result, CP/M is subject to more frequent
modification; so far, in the short life of the 128, there have
been at least three major revisions. Detailed technical infor-
mation on Commodore 128 CP/M is available in the book
CP/M Plus User's Guide /Programmer's Guide/System Guide,
available directly from Commodore.
Because this book is intended as a reference for intermedi-
ate to advanced BASIC and machine language programmers,
no attempt is made to provide simple explanations of all the
concepts discussed. The discussions assume familiarity with
elementary computer concepts such as bits and bytes, and
with memory quantity units such as a page (256 bytes) or a K
(kilobyte, 1024 bytes). The book also assumes familiarity with
the binary and hexadecimal numbering systems, although dec-
imal equivalents are usually provided.
Hexadecimal numbers in the text are always preceded by
a dollar sign ($), the standard 8502 nomenclature for hex.
Decimal numbers appear without any prefix. When you see a
pair of numbers separated by a slash (/), the first number is
vu
decimal and the second is hexadecimal, unless otherwise indi- data is to be retrieved or in which data is to be stored,
cated. This book uses the machine language monitor's conven- whereas a vector points to the address of a routine to be
tion of preceding binary numbers with a percent (%) sign. For executed.
example, %11 indicates the binary value equivalent to decimal A flag is a memory location in which individual bits are
3, not decimal 11. used to signal particular conditions. A binary bit can have one
When you see numbers mentioned in this book, it should of two conditions, %0 or %1 (also referred to as clear and set,
be obvious from the context whether the number refers to an respectively). The term comes from the analogy of flags, like
address or a value. Where there could have been confusion, the those on rural mailboxes, that can be either lowered or raised
terms value and location or address specify what is meant. In (there's no half-mast in binary). An example is the active
keeping with common practice, only two hexadecimal digits are screen flag, location 215/$D7. Bit 7 of the location is clear
generally used when discussing addresses in the first page of (%0) when the 40-column display is active, or set (%1) when
memory (zero page). That is, addresses 0-255 are usually writ- the 80-column display is active. (You'll find that flag locations
ten as $00-$FF. Four hexadecimal digits are used for all other often use bit 7 because that bit can be tested very easily in
addresses. For example, location 256 will be written as $0100, machine language with the BMI and BPL instructions.)
By nature, the computer prefers to deal with whole num- Chapter 1 provides a brief introduction to the way the
bers and doesn't handle fractions easily. Floating point is the 128 arranges and manages its memory resources. That chapter
method used to manipulate whole and fractional decimal and Chapter 4 are the only chapters in the book intended to
numbers in 128 BASIC. Floating point also enables very large be read from beginning to end. The remaining chapters de-
numbers to be handled in only a few bytes. All mathematical scribe the use or function of various areas of memory and
operations in BASIC are performed in floating point. (When should be used as an encyclopedic reference. The chapters
you specify integer variables in a mathematical operation, the generally cover memory in ascending address order, starting
integer value is converted to floating point for the operation; with zero page in Chapter 2 and ending with the Kernal jump
then the result is reconverted to integer format.) However, be- table at the very top of memory in Chapter 9. Each entry in
cause floating point is a rather complex subject, it is not ex- Chapters 2-9 consists of the decimal and hexadecimal address
plained in detail in this book even though it is mentioned of the location or routine; a label, if one is commonly used; a
extensively in Chapter 5. If you are interested in the inner short statement of the function of the location or routine; and
workings of floating point, refer to the excellent discussion of a short description of how the location or routine is used.
the topic in COMPUTED VIC-20 and Commodore 64 Tool Kit:
BASIC, by Dan Heeb. Although not written specifically for the
128, all the information about floating point applies to BASIC
7.0 as well.
Several terms used freely in this book need clarification.
Most locations discussed in Chapters 2 and 3 are either point-
ers, vectors, or flags. Pointers and vectors refer to a pair of
memory locations that hold an address. Two-byte address val-
ues in pointers and vectors are stored in low-byte/high-byte
order. That is, the least significant byte of the address should
be stored in the first byte of the pointer or vector, and the
most significant byte of the address in the second pointer or
vector byte.
The difference between pointers and vectors is that a
pointer (as the name implies) points to an address from which
IX
vm
Memory
Organization
The memory arrangement of a Commodore 128 in 128 mode
is much different and more complex than that of any of its
Commodore predecessors. As a result, it's necessary to under-
stand how the 128 organizes and manages its memory resources
before beginning a detailed examination of how those re-
sources are used. Of the computer's three possible personal-
ities, 128 mode is the default. Unless you take some other
action—holding down the Commodore key, inserting a Com-
modore 64 cartridge, placing a CP/M boot disk in the drive—
the computer comes up in 128 mode when you turn it on. As
the native mode of the system, 128 mode makes the most
complete use of the available memory resources.
You might be interested to learn that, while 128 mode is
the default operating mode, the computer always starts out in
CP/M mode. When you first turn on power, the Z80 micro-
processor has control before the 8502 is allowed to take over.
There are only a few signs of this: two short routines are cop-
ied into bank 0 RAM. One, at 65488/$FFD0, is an 8502 ML
routine that surrenders control to the Z80; the other, at
65504/$FFEO, is a Z80 ML routine that surrenders control to
the 8502. There are no routines in any of the 128 mode ROMs
to perform this initialization. However, once the Z80 com-
pletes its initialization sequence, it turns the system over to
the 8502 and 128 mode, and does not go back to CP/M mode
unless a CP/M disk is booted.
128 Mode
The 128 mode configuration includes 128K of random access
memory (RAM) in two 64K blocks, a 28K BASIC interpreter in
read only memory (ROM), a 4K machine language monitor in
ROM, 4K of screen editor routines in ROM, 8K of Kernal op-
erating system routines in ROM, a 4K character pattern ROM,
and 4K of address space for hardware chip registers (with two
separate IK banks of color RAM). The design also provides for
up to 32K of additional ROM internally and up to 32K of
ROM on cartridge. The operating system can support two ad-
ditional 64K banks of RAM, although the 128's design makes
no provision for adding memory chips. In sum, that's 373K of
address space, as illustrated in Figure 1-1.
This entire 373K address space must be manipulated by
the 8502 microprocessor that is the brains of the 128, but an
8502 can directly access only 64K of memory at a time. So
how is 128 mode even possible?
11
10
Common Working
Storage Area
The 128's memory management hardware has the ability to
create common areas of memory—areas where the same
memory will be seen regardless of the bank configuration. The
system allows up to 16K at both the top and bottom of the
processor's address space to be made common. However, the
operating system uses only part of this capability, setting up a
IK common area at the bottom of memory, locations 0-1023/
$0000-$03FF. No matter what bank configuration you choose,
the same block 0 RAM will be seen at these locations. It is this
common area, and especially the common routines in page 2,
that makes the 128's bank-switching operating system possible.
15
$00 $01
BASIC. You should be aware that any value stored in zero 1 $01 R85O2
page will be wiped out during a reset. The RAMTAS routine Data register for processor's on-chip I/O port
[$E093], part of the reset sequence, clears locations 2-255/ Each of the seven I/O lines on the 8502 microprocessor has a
$02-$FF to zero. (You can prevent this by holding down the corresponding bit in this location (bit 7 is unused). The direc-
RUN/STOP key during the reset which will cause the RAMTAS tion of data flow on the lines is controlled by location $00. If
step of the reset sequence to be skipped. In this case, the sys- an I/O port line is set for input, the corresponding bit here
tem will be left in the machine language monitor after the re- will reflect the state of the input line: %0 if the line is low (0
set rather than in BASIC.) volts), or %1 if the line is high ( + 5 volts). While a line is set
Unlike other Commodore computers, the 128 has the abil- for input, values written to the corresponding bit have no ef-
ity to make the 8502 see zero page anywhere in memory. The fect. If an I/O port line is set for output, its state will be con-
MMU (memory management unit) chip has a feature which al- trolled by the corresponding bit in this location. Storing a %0
lows the processor to exchange zero page with another page in the bit forces the output line to a low (0 volts) state, while
so that references to zero page are directed to the alternate storing a %1 in the bit sets the line to a high ( + 5v state).
page, and references to addresses in the alternate page are di- The I/O lines are connected as follows:
rected to zero page. See the discussion of the MMU in Chapter Bits 0-1: The lines connected to these bits control which of the
8 for details. The 128 does not normally make use of this fea- two IK blocks of color memory will be visible at 55296-56319/
ture; the default position for zero page is at the true zero-page
$D800-$DBFF when the I/O block is selected. For this pur-
locations.
pose, the lines should always be configured as outputs. Unlike
The first two addresses in this page have a special func- in the Commodore 64, these bits have no effect on whether
tion. The 8502 processor has a built-in I/O port, and it sees RAM or ROM is selected at a given address. In the 128, mem-
the registers for that port at locations 0-l/$00-$01. References ory management is the domain of the MMU chip. See Chapter
to those addresses always affect the port; the processor will 8 for more information.
never see the first two bytes of RAM. These locations are not Bit 0 controls which block the processor sees, while bit 1
affected by the page-swapping feature. Regardless of where controls which block the VIC chip sees. Setting either bit to
the remainder of zero page is currently seen, locations 0-1 are %0 selects block 0, while a setting of %1 selects block 1. The
used exclusively to control the internal port.
setting of these bits is established during the screen-setup por-
tion of the screen IRQ routine [$C194], That routine sets both
0 $00 D8502 bits to %1 for text mode (GRAPHIC 0), or for the text portion
Data direction register for processor's on-chip I/O port of the split-screen modes (GRAPHIC 2 or GRAPHIC 4). For
Bits 0-6 in this location control the direction of data flow for the bitmapped modes (GRAPHIC 1 or GRAPHIC 3) or for the
the seven I/O (input/output) lines on the 8502 microprocessor bitmapped portion of the split-screen modes, bit 1 is set to
chip, labeled P0-P6. Setting a bit to %0 makes the correspond- %0. Thus, the VIC sees different blocks of memory for the
ing line an input, and its state can be read at the correspond- modes, and drawing on the bitmapped screen will not disturb
ing bit position in location $01. Setting a bit to %1 makes the colors on the text screen. To manipulate these bits in other
corresponding line an output, and its state will be controlled ways, the screen-setup portion of the IRQ routine must be dis-
by the setting of the corresponding bit position in location abled. Refer to the discussion of the color memory area in
$01. The value here is initialized to 47/$2F by the IOINIT Chapter 8 for details on switching color blocks.
routine [$E109], part of both the reset and RUN/STOP-
Bit 2: The line for this bit, known as the CHAREN line, deter-
RESTORE sequences. This sets lines 0-3 and 5 for output and
mines whether the VIC chip will see character ROM in its cur-
lines 4 and 6 for input. Since only seven lines are provided,
rent video bank. For proper functioning, the line should be
bit 7 is not used. That bit will retain whatever value is written
configured as an output. While this bit is %0, the VIC chip
to it, but its setting has no effect.
16 17
$01 $02
will see character ROM beginning at an offset of 4096/$1000 MTR line, is turned off. Setting this bit to %0 turns on the 9-
from the start of the bank. The uppercase/graphics set will volt power supply to the motor. The setting of this bit is con-
appear to occupy locations with offsets of 4096-6143/ trolled by a shadow location, the cassette motor interlock at
$1000-$17FF, and the lowercase/uppercase set will appear at 192/SCO.
offsets of 6144-8191/$1800-$lFFF. The character sets will be Bit 6: The line for this bit is connected to the CAPS LOCK key
visible in all VIC video banks, not just banks 0 and 2 as was on the keyboard. The line should be configured as an input to
the case in the Commodore 64. Only the VIC chip will see the read the state of this key. The bit will return a %1 while the
character ROM at these addresses; the processor will still see key is in the up position (CAPS LOCK off), and a %0 when
the locations as RAM or system ROM, depending on the ad- the key is down (CAPS LOCK on). The status of this bit is
dress and bank configuration. read by the SCNKEY routine [$C55D] during each system
To disable this feature and allow the VIC chip to see IRQ, and bit 4 of location 211/$D3 will be assigned the oppo-
RAM at the character set image addresses, the CHAREN bit site setting of this bit.
must be set to % 1 . However, this cannot normally be done di-
rectly because this bit has a shadow at location 217/$D9. Dur- Bit 7: There is no I/O port line connected to this bit, so the
ing the text mode-setup portion of the screen editor IRQ value here is meaningless. The bit always returns a %0 when
routine [$C194], the value of bit 2 of the shadow location is read.
copied into this bit. Thus, to change this bit you should set bit
2 of the shadow location instead. If the screen-setup portion of 2 $02 BANK
the IRQ routine is disabled (by storing the value 255/$FF in Target bank for JMPFAR and JSRFAR
location 216/$D8, for example), the setting of this bit can then The value here determines the bank to which the JMPFAR
be changed directly. The IRQ routine always sets this bit to routine [S02E3] will jump. Because the JSRFAR routine
%1 for bitmapped screen modes or for the bitmapped portion [$02CD] calls JMPFAR as a subroutine, the value here also de-
of split-screen modes. termines the destination bank for a JSRFAR. This location
should be loaded with the number (0-15) of the desired bank
Bit 3: The line for this bit is connected to the CASS WRT (cas- before either JMPFAR or JSRFAR is used.
sette write) line of the cassette port. The setting of this bit de- The BASIC SYS statement is implemented using JSRFAR.
termines whether a signal is being written to the tape. For this In that case, the value here is set from the value in location
purpose, the line must be configured as an output. See Chap- 981/$03D5, which holds the parameter from the most recent
ter 9 for more information about the tape routines. BANK statement (15/$0F by default). The BASIC routine that
Bit 4: The line for this bit is connected to the CASS SENSE searches for a token in the runtime stack [$4FAA] also uses lo-
(cassette button sense) line of the cassette port. If the port line cation 2/$02 for temporary storage.
is configured as an input, this bit can be read to determine When the monitor is entered at the break entry point
whether any buttons are currently pressed on the Datassette. [$B003], this location is loaded with the bank number in
When no buttons are pressed (or when no Datassette is con- which the system was operating when the BRK opcode was
nected to the port), this bit will be % 1 . Pressing any button encountered. When the monitor is entered at the cold-start en-
will change this bit to %0. Unfortunately, the bit merely de- try point [$B000], as by the BASIC MONITOR command, this
tects whether buttons are pressed, and cannot indicate which location is initialized to 15/$0F (for bank 15). The monitor R
specific buttons. If you press FAST FORWARD when in- command displays the value in this location as the first hexa-
structed to press PLAY, the 128 won't notice the difference. decimal digit of the PC value. The register change (;) com-
mand can be used to alter the value stored here. The value
Bit 5: The line for this bit controls the CASS MTR (cassette determines the bank for the monitor G (go to routine) and J
motor) line of the cassette port. When this bit is % 1 , the (jump to subroutine) commands, which use JMPFAR and
power supply to the cassette motor, provided via the CASS JSRFAR, respectively.
18 19
3-4 $03-$04 $05 5
3-4 $03-$04 PC The contents of the status register upon return from the
Target address for JMPFAR and JSRFAR target routine are stored in this location before return from
The values here determine the address to which the JMPFAR JSRFAR, so you can read this location to determine the exit
routine [$02E3] will jump. Because the JSRFAR routine status of the routine. This is useful because system routines
[$02CD] calls JMPFAR as a subroutine, the value here also de- often use status register bits, particularly carry, to return infor-
termines the destination address for a JSRFAR. These locations mation about the success of the operation performed by the
should be loaded with the desired address before either routine.
JMPFAR or JSRFAR is used. Contrary to the normal order of
address bytes, the high byte of the target address should be Figure 2-1. 8502 Processor Status Register
stored in location 3/$03 and the low byte in location 4/$04.
When the monitor is entered at the break entry point
[$3003], these locations are loaded with the program counter
contents stored on the stack when the BRK opcode was en-
countered. Because of the way the microprocessor handles
BRK, this value will be two bytes beyond the address of the
BRK ($00) opcode. When the monitor is entered at the cold-
start entry point [$B000], as by the BASIC MONITOR com-
mand, these locations are initialized to 45056/$B000 (the cold-
start entry address). The monitor R command displays the
value in these locations as the four rightmost hexadecimal dig-
its of the PC value. The register change {;) command can be
used to alter the value stored here. The value determines the
target address for the monitor G (go to routine) and J (jump to
subroutine) commands, which use JMPFAR and JSRFAR,
respectively.
The BASIC 7.0 version of the SYS statement allows you
5 $05 S-REG to specify a status register value, which will be placed in this
Status register storage for JMPFAR and JSRFAR location before the JSRFAR to the specified address. The
The value in this location is transferred to the processor's sta- RREG statement can be used to read the value here. (The sta-
tus register when a routine is called with JMPFAR [$02E3]. Be- tus register value returned by RREG is actually the contents of
cause JSRFAR [$02CD] also uses JMPFAR, the value here will this location.)
also determine the initial status register value for a routine When the monitor is entered at the break entry point
called with JSRFAR. You can use this location to set up par- [$B003], this location is loaded with the status register contents
ticular entry conditions for the target routine. For example, stored on the stack when the BRK opcode was encountered.
certain system routines behave differently depending on When the monitor is entered at the cold-start entry point
whether the carry bit, bit 0 of the status register, is clear (%0) [$BO00], as by the BASIC MONITOR command, this location
or set (%1) when the routine is called. You can specify the en- is initialized to zero. The monitor R command displays the
try setting of the carry bit by setting bit 0 of this location. Fig- value in this location under the heading SR. The register
ure 2-1 shows the function of the various status register bits. If change (;) command can be used to alter the value stored here.
you don't need any special entry conditions, it's best to set The value determines the status register contents for the moni-
this location to 0/$00. tor G (go to routine) and J (jump to subroutine) commands,
which use JMPFAR and JSRFAR, respectively.
20 21
6 $06 $08 8
6 $06 A_REG to determine the exit X register value. The JSRFAR routine it-
Accumulator storage for JMPFAR and JSRFAR self uses the X register after return from the target routine, so
The value in this location is transferred to the processor's ac- you must look to this location for the X register value from the
cumulator {A register) when a routine is called with JMPFAR target routine.
[$02E3J. Because JSRFAR [$02CD] also uses JMPFAR, the The BASIC 7.0 version of the SYS statement allows you
value here will also determine the initial accumulator value for to specify an X register value, which will be placed in this lo-
a routine called with JSRFAR. You can use this location to set cation before the JSRFAR to the specified address. The RREG
up a particular entry value for the target routine. The contents statement can be used to read the value here. (The X register
of the accumulator upon return from the target routine are value returned by RREG is actually the contents of this
stored in this location before return from JSRFAR, so you can location.)
read this location to determine the exit accumulator value. The When the monitor is entered at the break entry point
JSRFAR routine itself uses the accumulator after return from [$B003], this location is loaded with the X register contents
the target routine, so you must look to this location for the ac- stored on the stack by the IRQ/BRK handler [$FF17]. When
cumulator value from the target routine. the monitor is entered at the cold-start entry point [$B000], as
The BASIC 7.0 version of the SYS statement allows you by the BASIC MONITOR command, this location is initialized
to specify an accumulator value, which will be placed in this to zero. The monitor R command displays the value in this lo-
location before the JSRFAR to the specified address. The cation under the heading XR. The register change {;) command
RREG statement can be used to read the value here. (The ac- can be used to alter the value stored here. The value deter-
cumulator value returned by RREG is actually the contents of mines the X register contents for the monitor G (go to routine)
this location.) and J (jump to subroutine) commands, which use JMPFAR and
When the monitor is entered at the break entry point JSRFAR, respectively.
[$B003], this location is loaded with the accumulator contents
stored on the stack by the IRQ/BRK handler [$FF17]. When 8 $08 Y_REG
the monitor is entered at the cold-start entry point [$B000], as Y register storage for JMPFAR and JSRFAR
by the BASIC MONITOR command, this location is initialized The value in this location is transferred to the processor's Y
to zero. The monitor R command displays the value in this lo- register when a routine is called with JMPFAR [$02E3]. Be-
cation under the heading AC. The register change {;) com- cause JSRFAR [$02CD] also uses JMPFAR, the value here will
mand can be used to alter the value stored here. The value also determine the initial Y register value for a routine called
determines the accumulator contents for the monitor G (go to with JSRFAR. You can use this location to set up a particular
routine) and J (jump to subroutine) commands, which use entry value for the target routine. The contents of the Y regis-
JMPFAR and JSRFAR, respectively. ter upon return from the target routine are stored in this loca-
tion before return from JSRFAR, so you can read this location
7 $07 X_REG to determine the exit Y register value.
X register storage for JMPFAR and JSRFAR The BASIC 7.0 version of the SYS statement allows you
The value in this location is transferred to the processor's X to specify a Y register value, which will be placed in this loca-
register when a routine is called with JMPFAR [S02E3J. Be- tion before the JSRFAR to the specified address. The RREG
cause JSRFAR [$02CD] also uses JMPFAR, the value here will statement can be used to read the value here. (The Y register
also determine the initial X register value for a routine called value returned by RREG is actually the contents of this
with JSRFAR, You can use this location to set up a particular location.)
entry value for the target routine. The contents of the X regis- When the monitor is entered at the break entry point
ter upon return from the target routine are stored in this loca- [$B003], this location is loaded with the Y register contents
tion before return from JSRFAR, so you can read this location stored on the stack by the IRQ/BRK handler [$FF17]. When
22 23
9 $09 $0D 13
the monitor is entered at the cold-start entry point [$B000], as 10 $0A ENDCHR
by the BASIC MONITOR command, this location is initialized
to zero. The monitor R command displays the value in this lo- Working storage for various routines
cation under the heading YR. The register change (;) command This location is used for several different purposes by a variety
can be used to alter the value stored here. The value deter- of BASIC routines. It serves as a counter of the number of dig-
mines the Y register contents for the monitor G (go to routine) its in the ASCII representation of a number during the routine
and J (jump to subroutine) commands, which use JMPFAR and which interprets the characters as a numeric value [$50A0]. It
JSRFAR, respectively. holds the value of the character which terminates the search in
the routine which looks for a particular character in a BASIC
program line [$52A2], and in the one that puts a string into
9 $09 STKPTR the string pool [$869A]. It is also used for temporary storage of
Stack pointer storage for JSRFAR and monitor intermediate values while performing BASIC AND or OR op-
This location is used in the JSRFAR routine [$02CD] to record erations [$4C86].
the value in the stack pointer upon return from the target rou-
tine. The value here doesn't affect the setting of the stack 11 $0B TRMPOS
pointer; it merely records the exit value. Current screen column for TAB and SPC calculations
When the monitor is entered via either the cold-start entry The value in this location is used during the portion of the
point [$B000] or the break entry point [$B003], the current BASIC PRINT routine [$5554] that handles the TAB and SPC
stack pointer value is stored in this location. The monitor R functions. In the computation of the target column for the TAB
command displays the value in this location under the head- or SPC, this location will hold the current cursor column
ing SP. The register change (;) command can be used to alter value.
the value stored here. The value here is restored to the
microprocessor's stack pointer before the JMPFAR in the G (go 12 $0C VERCK
to routine) command routine. This location will hold the stack
pointer value after a J (jump to subroutine) command, since BASIC LOAD/VERIFY flag
that routine uses JSRFAR. The same routine is used to perform both the load and verify
operations, so this flag indicates which is being performed, A
zero value here indicates a load operation, and a nonzero
9 $09 CHARAC or INTEGR value indicates verify. The value here is set during the
Working storage for various routines LOAD/VERIFY [$9129] and DLOAD/DVERIFY [$A1A4]
This location is used for several different purposes by a variety routines. Both operations use the Kernal LOAD routine
of BASIC routines. It serves as temporary storage in the rou- [$F265], which has its own load/verify flag at location
tine which interprets ASCII characters as numeric values 147/$93.
[$50A0]. It holds the value of the desired search character in
the routine which searches for a particular character in a 13 $OD COUNT
BASIC program line [$52A2], and in the routine that puts a Working storage for various routines
string into the string pool [$869A]. It holds the low byte of the This location is used for different purposes by several BASIC
integer value generated in the BASIC INT routine [$8CFB]. It routines. It holds the most recently found token during pro-
is also used for temporary storage of intermediate values while gram tokenization [$430A]. In the routine that adds or deletes
performing BASIC AND or OR operations [$4C86], BASIC program lines [$4DE2], this location holds the length of
the current line. It is also used as a counter in the RREG rou-
tine [$50BD], and as a counter in the subroutines that find or
create array-variable elements.
24
25
14 $0E $15 21
26
27
22-23 $16-$17 $24-$25 36-37
Statements which get input or send output to other devices, 24 $18 TEMPPT
such as GET#, INPUT#, and PRINT*, will temporarily change Pointer into temporary string descriptor stack
the value here to the channel number specified in the statement. The value in this location points to the next available slot in
The CMD statement can also be used to change the value the temporary string descriptor stack at 27-35/$lB-$23. This
here and direct all output to a specified logical file. However, location can have the following values:
you can't depend on CMD (or POKEing a value here) to keep
all output flowing to the specified logical file. A number of Value Meaning
other BASIC statements reset the value here to 0/$00 each 27/$lB no entries (stack empty)
time they are executed, restoring default input and output de- 3O/$1E one entry
33/$21 two entries
vices. These statements include GET (and GET# and GETKEY), 36/$24 three entries (stack full)
INPUT#, and PRINT*.
25-26 $19-$1A LASTPT
22-23 $16-$ 17 LINNUM Pointer to most recent descriptor stack entry
Integer value of ASCII digit string These locations hold the address of the most recent entry in
These are very busy locations, since the routine which reads the temporary string descriptor stack at 27-35/$lB-$23. Loca-
ASCII characters from program text and converts the result to tion 25/$19 will hold the equivalent of the value in 24/$18
a two-byte line number value [$50A0] stores its results here. less three, and location 26/$lA will hold zero (it is assigned
Other routines which manipulate program lines, such as the this value during the BASIC cold-start sequence). For example,
one which adds or deletes program lines, will use these loca- when there are two entries on the stack, 24/$18 will hold $21,
tions to hold the line number. Any statement which reads a while these two locations will hold $1E and $00, correspond-
line number, including GOTO, GOSUB, LIST, and so on, will ing to address $001E, the address of the second entry in the
expect to find the target line number in these locations. The stack.
TRAP destination line number is held here during the ERROR
routine [$4D3C], and the COLLISION target line number is 27-35 $ lB-$23 TEMPST
held here during the GONE routine [$4A9F].
Temporary string descriptor stack
Machine language programmers can store line number The three 3-byte entries here hold descriptors (length plus a 2-
values in these locations, then jump into a BASIC routine at a byte pointer to the starting address of the string in the string
point beyond the line number evaluation step. For example, a pool) for strings being evaluated or assembled. For strings be-
machine language program can enter a BASIC program at any ing assigned to variables, the descriptor value generated here
line number by jumping into the GOTO routine with the tar- will be transferred to the variable table entry for that string,
get line number in these locations. The following section of
code performs the equivalent of GOTO 100: 36-37 $24-$25 INDEX
LDA #$64 ;Place line number in $16-$17. Multipurpose address pointer
STA $16 These locations are used as an address pointer by several
LDA #$00 BASIC routines, including the one at 927/$039F, which re-
STA $17
trieves characters from bank 0 (BASIC program text), and the
LDA #$0F ;Bank number for BASIC ROM (15). one at 951/$03B7, which retrieves characters from bank 1
STA $02 (BASIC string storage). Numerous BASIC routines call those
LDA #$59 ;Enter GOTO routine at $59FB. character retrieval routines, including the one which inserts or
STA $03
LDA #$FB deletes program lines [$4DE2] and the one which updates
STA $04 variable tags while making space for a new variable. The
JMP $02E3 ;Use JMPFAR to call routine.
28 29
38-39 $26-$27 $31-$32 49-50
pointer is also used in the LIST routine to read characters from 7169/$1CO1 when the graphics area is de-allocated and the
the keyword table, and in the floating-point routines to copy BASIC program text is moved back down to its original
floating values to and from the variable storage area in bank position.
1. In addition, location 36/$24 is used for temporary storage During the NEW and RUN routines, the CHRGET pointer
during formula evaluation, and location 37/$25 is used as a (61-62/$3D-$3E) is initialized with a value one less than the
pointer into the ROM keyword tables when tokenizing pro- address in these locations. You can store new values in these
gram lines [$43E2] or listing (detokenizing) program lines locations to change the starting position of BASIC program
[$5123]. text—for example, if you wish to reserve free memory space in
block 0 RAM below the program. However, two other steps are
38-39 $26-$27 INDEX2 required to properly initialize the system to use the new start-
Multipurpose address pointer ing position: You must also store the value 0/$00 in the loca-
These locations are used as an address pointer by the routine tion immediately before the address specified here (BASIC
at 960/$03C0 which fetches characters from BASIC program requires that program text be preceded by a zero byte), and
text in bank 0. That routine is called by several other BASIC you must perform a NEW to reset other pointers to reflect the
routines, including the one which adds or deletes program new start-of-BASIC position.
lines. These locations are also used by the ERROR routine During execution of BASIC'S SAVE and DSAVE routines,
[$4D3C] as a pointer to the specified error message in the mes- the value here determines the starting address of the data to be
sage table in ROM. saved.
30
31
51-52 $33-$34 $3B-$3C 59-60
locations 47-48/$2F-$30 during the CLR routine [$51F8] performed to remove inactive strings. If garbage collection
(which is also performed during NEW and BASIC cold start). cannot remove enough unused strings to create free space be-
tween the address here and the one in 51-52/$33-$34, an
51 -52 $33-$34 STREND OUT OF MEMORY error occurs. The function FRE(l) will re-
Start-of-free-memory pointer turn the difference between the value here and the one in lo-
The value in these locations points to the lowest address in cations 51-52/$33-$34, the amount of free memory remaining
block 1 RAM available for the storage of strings, which is also for string storage.
one location above the last address used for array variables.
The value here is initialized to the start-of-variables value in 55-56 $37-$38 FRESPC
locations 47-48/$2F-$30 during the CLR routine [$51F8] Temporary pointer into the string pool
(which is also performed during NEW and BASIC cold start). These locations are used by the routines that add strings to the
When the value here equals the value in location 49-50/ string pool as a pointer to the currently referenced string, and
$31-$32, no arrays are being used. The function FRE(l) will as a pointer to the current string during the garbage collection
return the difference between the value here and the one in routines.
locations 53-54/$35-$36, representing the remaining amount
of memory available for string storage. When the value in
57-58 $39-$3A MAX_MEM_1
53-54/$35-$36 (the FRETOP pointer) reaches the value here,
Top-of-memory pointer
garbage collection is performed. If garbage collection cannot
remove enough unused strings to create free space between The value in these locations determines the highest address in
the address here and the one pointed to by FRETOP, an OUT block 1 RAM available for the string pool. (Actually, the ad-
OF MEMORY error occurs. dress value here will be one location beyond the highest loca-
tion used for the string pool.) The string pool is filled down-
ward from the address specified here. The value in locations
53-54 $35-$36 FRETOP 53-54/$35-$36 specifies the address of the bottom of the
Bottom-of-string-space pointer pool. When the value in those locations equals the value here,
The value in these locations points to the lowest address in the pool is empty. The BASIC cold-start routine initializes
block 1 RAM used for the string pool. All character strings these locations to 65280/$FFO0, one location beyond the high-
used in a BASIC program are stored in the area of block 1 be- est contiguous address in block 1 RAM (MMU registers are
tween the address pointed to in 57-58/$39-$3A and the ad- seen at 65280-65284/$FF0O-$FFO4 in all memory configura-
dress pointed to here—an area called the string pool. Each tions). You can reduce the value here to reserve memory at
active string here will have a descriptor in the variable array the top of block 1 for other purposes such as data storage.
table areas at the bottom of block 1, or in the temporary de- However, when you change the value here you should also
scriptor stack at 27-35/$lB-$23. The pool may also contain execute a CLR statement [$51F8] to reset the other string pool
inactive strings that the program is no longer using. The value pointers,
here is initialized to the top-of-memory value in locations
57-58/$39-$3A during the CLR routine [$51F8] (which is also 59-60 $3B-S3C CURLIN
performed as part of NEW and the BASIC cold-start sequence). Current BASIC line number
When the value here equals the value in location These locations hold the line number of the BASIC program
57-58/$39-$3A, no strings have yet been used. Strings are line currently being executed. After each program line is exe-
added from the top of memory downward. When the value cuted, the routine which executes BASIC program lines
here reaches the value in 51-52/$33-$34, garbage collection is [$4AF3] will load these locations with the number of the next
line to be executed. The value here is used by various other
32 33
61-62 $3D-$3E $43-$44 67-68
BASIC routines that need to know which line is currently be- 63-64 $3F-$40 FNDPNT
ing executed, The value here is stored in locations 4608-4609/ Working pointer for various routines
$1200-$1201 by the routine that processes STOP or END These locations are used as a working pointer into the runtime
[$4BCA]. The value stored in those locations will be trans- stack at 2048-2559/$0800-$09FF by the routines that search
ferred back here by the CONT routine [$5A60]. The value for tokens in the stack. The RENUMBER routine [$5AF8] uses
here will be stored in locations 4617-4618/$1209-$120A these locations as an end-of-program pointer. The PRINT
when an error is processed by the ERROR routine [$4D3C]. USING routine [$9520] uses the routine at 939/$03AB (which
The value in those locations will be transferred back here by uses these locations as a pointer) to retrieve characters from
the RESUME routine [$5F62], the template pattern string in block 1 RAM.
61-62 $3D-$3E TXTPTR 65-66 $41-$42 DATLIN
Pointer for main BASIC character retrieval routine Line number of current DATA statement
These locations serve as the pointer into BASIC text for the These locations hold the line number of the BASIC program
CHRGET routine, BASIC'S primary character retrieval routine. line containing the DATA statement from which DATA items
In earlier Commodore computers, the entire CHRGET routine are currently being read. These locations are updated by the
was in zero page. The 128's CHRGET is located higher in the subroutine that searches for the start of the next DATA state-
common area, beginning at address 896/$0380, and only the ment: [$57CA], called during execution of the READ state-
pointer is kept in zero page. CHRGET is designed to retrieve ment. The value here isn't used by any system routine, but it
the next nonspace character of BASIC text, so the first step in can be very helpful when you're debugging a program con-
CHRGET is to increment the address here. The routine also taining DATA statements. Whenever a program stops with an
has an alternate entry point called CHRGOT at 902/$0386, ILLEGAL QUANTITY or TYPE MISMATCH error message in
which retrieves the current character (the one at the address a line containing a READ statement, it's very likely that the
here) without incrementing the pointer. error is actually in the DATA line rather than the line speci-
The NEW, RUN, and LOAD routines all call the subroutine fied in the error statement (the one which contains READ).
[$5254] which initializes this pointer to one byte before the You can find the line number from which the last, possibly er-
start-of-BASIC value in locations 45-46/$2D-$2E. Because the roneous, DATA item was read using PRINT PEEK(65) + 256
CHRGET routine is so heavily used, many BASIC routines af- * PEEK(66).
fect the value here. For example, any of the routines which send
the program to another line, such as GOTO, GOSUB, THEN, 67-68 $43-$44 DATPTR
and so on, must replace the current value here with the ad- Pointer to next DATA item
dress of the target line. The value here is stored in locations These locations are used as a pointer to the address at which
4610-4611/$1202-$1203 by the routine that processes STOP the search for the next available DATA item will begin. The
or END [$4BCA]. The value stored in those locations will be subroutine that searches for the next DATA item [$57CA],
transferred back here by the CONT routine [$5A60]. The value called during execution of the READ statement, will update
here will be stored in locations 4622-4623/$120E-$120F the value here to point to the start of the next DATA item.
when an error is processed by the ERROR routine [$4D3C], The RESTORE statement, when used without a line number
The value in those locations may be transferred back here by parameter, resets the value here to the starting address of
the RESUME routine [$5F62]. BASIC program text (from locations 45-46/$2D-$2E), That
The value here is also used as a pointer for the alternate RESTORE subroutine is also called as part of the CLR routine,
character retrieval routine at 969/$03C9, which fetches the which in turn is called as part of RUN. Thus, the search for
current text character without CHRGET's test for character type. DATA items normally begins at the first program line. The
34 35
69-70 $45-$46 $4F 79
RESTORE statement can be used with a line number param- defined function) routine will load these locations with the ad-
eter to change the value here. In that case, the pointer value dress of the descriptor for the dummy variable in the function
will be reset to the starring address of the specified line. The definition,
specified line need not contain a DATA statement. It merely
specifies the line from which the search for the next DATA 75-76 $4B-$4C FORPNT
statement will begin. Variable descriptor pointer and working storage
These locations are used during the routine that assigns vari-
69-70 $45-$46 INPPTR able values (LET [$53C6]) as a pointer to the variable value or
Text pointer for input string descriptor. For numeric variables, the address here will
The common input routine [$56B2], used in the execution of be the location in block 1 RAM where the value will be
the GET, GETKEY, GET#, INPUT, INPUT*, and READ state- stored. For string variables, the address here will be the loca-
ments, uses these locations as a pointer to the characters to be tion in block 1 RAM where the length and pointer into the
read as input. The value here will be transferred into the string pool for the string will be stored. The FOR statement
CHRGET pointer at 61-62/$3D-$3E so that CHRGET can be uses the value here to find the address of the value for the
used to retrieve characters from the input. The GET, GETKEY, loop index variable.
and GET* statements will initialize the value here to For the WAIT statement [$6C2D], location 75/$4B holds
513/$0201, an input buffer location set to 0/$00 to cause the the test byte pattern and location 76/$4C holds the mask byte
input routine to read the next character. The INPUT and IN- pattern. Location 75/$4B is also used as an index into the cur-
PUT* statements will initialize the value here to 511/$01FF, a rent line during the routine to list BASIC program lines [$5123],
location immediately before the input buffer set to 44/$2C,
the code for the comma character. The actual input will be in 77-78 $4D-$4E VARTXT
the input buffer beginning at 512/$0200. The READ statement Temporary storage for text pointer
will initialize these locations with the starting address of the These locations are used for temporary storage for the
next DATA item (from locations 67-68/$43-$44). CHRGET pointer value from 61-62/$3D-$3E during the com-
mon input routine [$56B2], which uses CHRGET to retrieve
71-72 $47-$48 VARNAM characters from the input source location. Location 77/$4D is
Current variable name also used during the numeric expression evaluation routine
These locations are used during the routine to find or create a [$77EF] as a flag to indicate when the end of the expression
variable [$7AAF] to hold the compressed (two-byte) form of has been reached.
the specified variable name. This compressed form will then
be used as a search pattern to check whether a variable of the 79 $4F OPMASK
same name and type currently exists. If not, the characters Relational operator flag
here will be used as the name for the new variable. When the main expression evaluation routine [$77EF] finds a
relational operator (<, =, or >) in the current expression, it
73-74 $49-$4A VARPNT stores a value here indicating which operator has been found.
Pointer to variable descriptor For greater than (>) operations, the value here will be 1. For
These locations are used as a pointer to the first byte of the equals ( = ), the value will be 2; for less than (<) it will be 4.
descriptor for the variable—the address of the location just be- When the expression is evaluated, this value will be trans-
yond the two-character name in the variable table entry for ferred to location 20/$14.
the variable. The value here is set upon exit from the routines
to find [$7AAF] or create [$7B90] a variable. The FN (user-
36 37
80-81 $50-$51 $5D-^$5F 93-95
80-81 $5O-$S1 DEFPNT cold-start sequence with the value 76/$4C, the 8502 JMP
Defined function pointer and working pointer opcode. The function dispatch routine [$4BF7] loads 87-88/
These locations are used by the routine that retrieves bytes $57-$58 with the address of the routine that performs the de-
from the variable table entry for a function definition (FN). sired function operation. A JSR $0056 instruction then exe-
That routine [$42CE] uses these locations as a pointer for one cutes the function-handling routine.
of the bank 1 character retrieval subroutines [$03AB]. These
locations are also used as a working pointer by one of the 89-93 $59-$5D TEMPF1
routines that reads values during garbage collection. That rou- Floating-point work area
tine [$42FB] also uses a bank 1 data retrieval subroutine [$03AB]. These locations are used as a temporary floating-point work
The routine that allocates the bitmapped graphics area [$9F4F] area during the series evaluation routine [$9086] for the LOG,
uses these locations to hold the number of bytes that must be SIN, COS, TAN, and ATN functions. Location 89/$59 is also
moved upward to make room for the graphics area. used for temporary storage during the routine [$9D7C] which
subtracts the contents of one pair of bitmapped graphics stor-
80-84 $50-$54 TEMPF3 age locations from the contents of another pair of locations.
Temporary storage for floating-point value
These locations are used to temporarily hold the floating-point 90-91 $5A-$5B ARRYPNT
value of the exponent during the routine to handle the ex- Multipurpose working pointer
ponentiation (T) operator [$8FC1]. These locations are used as a pointer to the destination of text
being moved in the routine to add new BASIC program lines
82-83 $52-$53 DSCPNT to memory [$4DE2] and as a pointer into array space when
Variable address storage and working pointer making room for a new variable [$7B90]. They are also used to
The routine that creates space in the string poo] for a new string hold the line link value during RENUMBER [$5AF8].
variable uses these locations to temporarily store the address
of the variable table entry. These locations are also used as a 92-93 $5C-$5D HIGHTR
pointer by the routine that retrieves characters from the string Multipurpose address pointer
poo] for the LEFT$, RIGHT$/ and MID$ functions [$42D8]. These locations serve as a pointer for the routine that reads
the source text being moved in the routine to add new BASIC
85 $55 HELPER program lines. This routine [$42DD] uses one of the common
HELP flag bank 0 character retrieval routines [$039F]. The locations serve
Bit 7 of this location is tested in the routine which lists BASIC as a pointer in the routine to read source bytes when creating
program lines [$5123] to determine whether the line is being space for new variables. This routine [$42E2] uses one of the
displayed by LIST or by HELP. When the bit is % 1 , the sub- common bank 1 character retrieval routines [$03AB]. The loca-
routine at 22956/$59AC will be called to highlight the portion tions are used during the RENUMBER routine [$5AF8] to hold
of the line where the most recent error occurred. The HELP the number of the line currently being renumbered.
statement routine [$5986] sets bit 7 to %1 before it calls the
line-listing routine, and clears it to %0 afterwards. 93-95 $5D-$5F STR1
String length and pointer for MID$
86-88 $56-858 JMPER When MID$ is used as a statement [$5901] (to add characters
BASIC function execution vector to a string), these locations hold the descriptor of the original
This vector is used to execute the routines that handle BASIC string. Location 93/$5D holds the length, and locations
functions. Location S6/$56 is initialized during the BASIC 94-95/$5E-$5F hold the address and are used as a pointer.
38 39
94-98 $5E-$62 $63-$67 99-103
94-98 $5E-$62 TEMPF2 and 104/S68 for the bank value.) The starting address is sub-
Temporary storage for floating-point value tracted from the ending address, and the result is transferred
These locations are used to store an intermediate value from to 99-101/$63-$65. The value in those locations is then used
floating-point accumulator #1 (FAC1) during the series evalua- as a count of bytes to be affected by the operation. The
tion routine [$909C] for the EXP function. compare/transfer routine [$B231], which accepts three address
parameters, uses 102-104/$66-$68 as the pointer to the
source address for the compare or transfer and 96-98/$60-$62
94-95 $5E-$5F as the pointer to the destination address.
Working pointer for garbage collection Some monitor routines also make alternate use of some of
These locations are used as a pointer to the tag bytes for the these locations. The memory display routine [$B152] uses
current string during the routine that performs string pool gar- 96-98/$60-$62 as a count of lines to be displayed. During as-
bage collection [$92EA]. sembly [$B406], 99/$63 holds the length of the current in-
struction, and location 100/$64 holds the addressing mode
95 $5F DECCNT type. Locations 99-100/$63-$64 are used to unpack mnemon-
Decimal point position ics during disassembly [$B6A1], and 99/$63 serves as a
This location is used during the routine [$8E42] that creates a counter during directory display [$BB03].
character string representing the value in floating-point accu-
mulator #1 (FAC1) to hold the position within the string for 97-98 $61-$62 LOWTR
the decimal point. The location is also used as a loop counter Multipurpose address pointer
in the routine [$7E3E] to calculate the amount of memory A wide variety of BASIC routines use these locations as a
needed for an array. pointer. They serve as the pointer for a heavily used routine
[$42EC] to read characters from BASIC program text. (That
96-98 $60-$62 STR2 routine uses one of the common bank 0 character retrieval
Substring length and pointer for MID$ subroutines [$039F].) The routine is called by the routine
When MID$ is used as a statement [$5901] (to add characters which adds or deletes program lines [$4DE2], the one which
to a string), these locations hold the descriptor of the substring searches for a line number [$5064] (in which case the starting
to be added. Location 96/$60 holds the length, and locations address of the line is returned in these locations), LIST
97-98/$61-$62 hold the address and are used as a pointer. [$50E2], and DELETE [$5E87]. These locations also serve as
the pointer for a routine [$4300] to read values from the vari-
96-104 $60-$68 T0-T2 able table. (That routine uses one of the common bank 1 char-
Monitor zero-page pointers and working storage acter retrieval subroutines [$03AB].) The routine is called by
These locations are used by many routines in the monitor. The the routine [$7AAF] which searches the variable table to check
monitor routine [$B7CE] that determines the numeric value of whether a variable with a specified name already exists, and
a parameter in the input buffer leaves the value in locations the one [$7CAB] which performs a similar search for array
96-98/$60-$62 (in low- to high-byte order), so any numeric names. If an existing name is found, the address of the table
value in a monitor command is at least initially held there. For entry for the variable or array will be returned in these
monitor commands that accept two or more address param- locations.
eters, the first address is transferred into locations 102-104/
$66-$68, and the value there is then used as a working 99-103 $63-$67 FAC1
pointer to the byte to be read or written. (The monitor's indi- Floating-point accumulator 1
rect fetch [$B11A], indirect store [$B12A], and indirect compare These locations are the primary work area for all routines
[$B13D] routines use 102-103/$66-$67 for the address pointer which use floating-point math, which includes all of BASIC'S
40 41
104 $68 $70-$71 112-113
113 $71 FACOV ized to 0/$00 (no graphics area) during the BASIC cold-start
Rounding flag for FAC1 sequence. When the graphics area is allocated, this location is
When a pair of floating-point mantissas are adjusted for a decremented (to 255/$FF). The only BASIC statement that re-
math operation, any extra bits that must be shifted out of the sets this location is GRAPHIC CLR-—the value here isn't af-
smaller mantissa are held here and used to round the final re- fected by NEW or CLR—so once a graphics area is allocated it
sult to extend the accuracy of the operation. will remain allocated until the computer is reset or a GRAPHIC
CLR statement is executed.
114-115 $72-$73 STRNG2
Multipurpose address pointer and working storage 119 $77 Z_P_TEMP_1
In the series evaluation routine, these locations are used as a General-purpose working storage
pointer to the constant values used in the series evaluation. In This location is used for temporary storage by a variety of
the VAL routine [$804A], these locations are used as a pointer BASIC routines.
into the character string to be translated into a floating-point
value. These locations are used as working storage in the 120 $78 HULP
routines that calculate the amount of memory required for an String offset pointer
array. In the DEC routine [$8072], these locations are used as This location is used during the routine [$5901] that handles
a work area for converting the hexadecimal string characters MID$ as a statement to hold the offset from the start of the
into a two-byte integer value. string to the substring being replaced. It's also used during the
PLAY string-processing subroutine [$6DE1] to hold the offset
116-117 $74-$75 AUTINC to the next character waiting to be processed in the string.
Step value for autoincretnent
These locations hold the step value for automatically incre- 121 $79 SYNTMP
menting the line number if autoincrement mode is active. Multipurpose temporary storage
After each BASIC program line is entered while this mode is This location is used for temporary storage by a number of
active, the value here will be added to the previous line num- different BASIC routines.
ber and the resulting new line number will be printed on the
screen. Autoincrement mode will be active whenever these lo- 122 $7 A MTXTPTR
cations contain a nonzero value. These locations are reset to Index into input buffer for monitor
0/$00 during the BASIC cold-start sequence, and during the The monitor uses this location to store the position of the
RUN subroutine [$5A81] that resets flags. The value here can next character to be read from the input buffer (512-672/
be set using the AUTO statement. $0200-$02A0).
46 47
132 $84 $89-$8A 137-138
132 $84 MULTICOLOR_1 matrix fill byte at 994/$03E2 and the multicolor video matrix
fill byte at 995/$03E3. One of these values, depending on the
Color source 2 storage display mode, will be used to fill the video matrix area when
This location holds the current color number for color source the bitmapped screen is cleared. Thus, the value here eventu-
2. The value here doesn't have any immediate effect on the ally determines the color of standard bitmapped pixels repre-
screen display, but whenever the COLOR statement routine sented by %1 bits or of multicolor bitmapped pixels represented
[$69E2] is executed, the lower four bits of the value here will by %10 bit pairs. During the BASIC cold-start sequence, this
be copied into the lower four bits of the multicolor video ma- location is initialized to 13/$0D (light green). The value here
trix fill byte at 995/$03E3. That value will be used to fill the can be changed using the statement COLOR \,n, where n is a
video matrix area when the multicolor bitmapped (GRAPHIC standard BASIC color number (1-16). Remember that the color
3) screen is cleared. Thus, the value here eventually deter- change is effective only after the screen is cleared.
mines the color of multicolor bitmapped pixels represented by
%10 bit pairs. This is the bit pattern that will be produced for
lines drawn when color source 2 is specified. During the 135-136 $87-$88 SCALE_X
BASIC cold-start sequence, this location is initialized to 1 Horizontal scaling factor
(white). The value here can be changed using the statement These locations hold the horizontal scaling factor for BASIC
COLOR 2,n, where n is a standard BASIC color number graphics routines. If scaling is in effect (indicated when the
(1-16). Remember that the color change is effective only after scaling flag at 4458/$116A holds a nonzero value), the speci-
the multicolor bitmapped screen is cleared. fied horizontal (x) coordinates for all graphics routine param-
eters will be adjusted according to the value here to get the
133 $85 MULTIC0L0R-2 true bitmap coordinates. The value here can be changed using
the SCALE statement. If the first parameter in the statement is
Color source 3 storage 1 (scaling on), the factor here is calculated from the second pa-
This location holds the current color number for color source rameter according to the following formula:
3. The value here doesn't have any immediate effect on the
screen display, but whenever the bitmapped screen is cleared, scaling factor = (65535 * 320)/scaling parameter
block 0 of color memory (55296-56319/$D800-$DBFF) is If the parameter is omitted, a default value of 20480/$5000
filled with the value here. Thus, the value here eventually de- (for a bitmapped screen) or 10240/S2800 (for a multicolor bit-
termines the color of multicolor bitmapped pixels represented mapped screen) is supplied. This allows a scaled screen of
by %11 bit pairs. This is the bit pattern drawn for lines when 1024 horizontal positions (x coordinates 0-1023).
color source 3 is specified. During the BASIC cold-start se-
quence, this location is initialized to 2 (red). The value here 137-138 $89-$8A SCALE-Y
can be changed using the statement COLOR 3,Ji, where n is a Vertical scaling factor
standard BASIC color number (1-16). Remember that the color These locations hold the vertical scaling factor for BASIC
change is effective only after the multicolor bitmapped screen graphics routines. If scaling is in effect (indicated when the
is cleared.
scaling flag at 4458/$116A holds a nonzero value), the speci-
fied vertical {y) coordinates for all graphics routine parameters
134 $86 FOREGROUND will be adjusted according to the value here to get the true bit-
Current foreground color (source 1) storage map coordinates. The value here can be changed using the
This location holds the current color number for color source SCALE statement. If the first parameter in the statement is 1
1. The value here doesn't have any immediate effect on the (scaling on), the factor here is calculated from the third param-
screen display, but whenever the COLOR statement routine eter according to the following formula:
[$69E2] is executed, the lower four bits of the value here will scaling factor = (65535 * 200)/scaling parameter
be copied into the upper four bits of both the standard video
48 49
139 $8B $91 145
If the parameter is omitted, a default value of 12800/13 200 is Bit Bit value Serial bus Tape
supplied. This allows a scaled screen of 1024 vertical positions 0 l/$01 timeout during write
1 2/S02 timeout during read
(y coordinates 0-1023). 4/$04 short block
2
(leader read where data expected)
139 $8B STOPNB 8/$08 long block
(data read where leader expected)
PAINT mode flag unrecoverable read error
16/$10 mismatch during
Bit 7 of this location is used during the PAINT statement rou- verify {or mismatch during verify)
tine [$61A8] to specify whether the fill stops at pixels where 32/$20 checksum mismatch for block
the source color is encountered (indicated when the bit is %0) 64/$40 EOI (end of file) end-of-file marker read
or whether all nonbackground pixels will be filled (indicated 128/$80 device not present end-of-tape marker read
when this bit is %1). This location is normally set according to In BASIC, the reserved variable ST returns the value here
the fourth parameter of the PAINT statement, to 0/$00 if the when the current I/O device is tape (1) or serial (4 or larger).
parameter is 0 or omitted, or to 128/$80 if the parameter is 1. For RS-232 operations, the status is instead recorded in loca-
tion 2580/S0A14.
140-141 $8C-$8D GRAPNT 145 $91 STKEY
Address pointer for graphics routines Scan value of STOP key column
These locations are used as an address pointer by several This location holds the current status of the keyboard column
BASIC graphics routines. The value here points to the address containing the RUN/STOP key. The Kernal UDTIM routine
within the bitmap where a character pattern will be copied [$F5F8], which is part of the system jiffy IRQ sequence, in-
during CHAR [$67D7]. The locations serve as a pointer to the cludes a section which reads the current column of the key-
area being filled during the SCNCLR [$6A79]. In the general board matrix. (See Figure 7-1 in Chapter 7 for a diagram of
pixel-drawing routine, these locations point to the bitmap ad- the keyboard matrix.) The current state of that column is
dress where the pixel will be drawn. stored in this location (unless the key connected to row 7 of
the column has been pressed at the same time as some key in
142-143 $8E-$8F VTEMP columns 1 or 6, which contain the SHIFT keys). The proper
Temporary storage for graphics routines functioning of this routine depends on the fact that the
These locations are used for temporary storage by a variety of SCNKEY routine [$C55D], normally performed earlier in the
BASIC graphics routines. IRQ sequence, leaves the system set to scan column 7, the one
containing the RUN/STOP key (in row 7). When the Kernal
144 $90 STATUS STOP routine [$F66E] is called to determine whether the
Status flag for tape and serial bus operations RUN/STOP key is currently pressed, it checks this location
This location records the status of the most recent tape or se- rather than actually reading the keyboard.
rial bus operation. In general, when the operation has been This location can also be used to read any of the other
successful the value here is 0/$00, while a nonzero value indi- keys in column 7. The value here will be 255/$FF when no
cates that an error has occurred or that the end of the file has key in that column is pressed. Pressing a key sets a cor-
been reached. The value here is reset to zero at the beginning responding bit here to %0. The values here when the respec-
of any load or save, or whenever a file is opened to tape or a tive keys are pressed are as follows:
serial device. Various error conditions are indicated by setting Key Bit Value Key Bit Value
particular bits to % 1 . The bits are used as follows: 0 254/$FE space 4 239/$EF
*- 1 253/$FD Commodore 5 223/$DF
CONTROL 2 251/$FB Q 6 191/$BF
2 3 247/$F7 RUN/STOP 7 127/$7F
50 51
146 $92 $9A 154
output by the CKOUT routine, the device number value for 158 $9E PTR1
the file is read from that file's entry in the device number ta- Tape pass 1 error-log pointer
ble at 876-885/$036C-$0376 and stored here. The CLRCH The Commodore tape system records two copies of each block
routine will reset the value here to 0/$00, to make the screen of data written to tape. If errors are detected while the first
the default output device. copy is being read, the address where the erroneous byte is lo-
cated is stored in the tape error-log area at the bottom of page
155 $9B PRTY 1, This location is used as an offset to the next available two-
Tape character parity byte address slot in the error log. The value here is reset to
This location is used during routines which read from tape to 0/$00 at the beginning of the operation. An unrecoverable er-
calculate the parity of the byte currently being read. Bytes ror occurs if the value here exceeds 60/$3C, indicating that
stored on tape have an extra parity bit added to make an odd more than 31 errors have been logged.
total number of %1 bits in the combined character (eight data This location is also used to hold the offset into the speci-
bits plus parity). This location is used to make sure that an fied filename during the routine which checks to determine
odd total number of bits is read back for each character. whether a particular tape header has been found, and for tem-
porary storage of the type identifier byte when header blocks
156 $9C DPSW are being written to tape.
Tape dipole received flag
This location is used when a byte is being read from tape to 159 $9F PTR2
indicate whether all bits of the byte have been received (indi- Tape pass 2 error-log pointer
cated by a nonzero value), or whether bits are still being read This location is used during the routine which reads the sec-
(indicated by a value of 0/$00). ond copy of each tape data block to indicate the offset to the
next slot in the tape error log. That slot will contain the ad-
157 $9D MSGFLG dress of the next byte that needs correcting in the second pass.
Kernal message control flag This location is also used to hold the offset into the filename
This location controls whether Kernal messages will be dis- in the tape header when the routine is checking whether a
played. The Kernal routines have two types of messages: con- particular tape header has been found.
trol messages (PRESS PLAY ON TAPE, SEARCHING FOR, The monitor assemble routine [$B406] also uses this
and so on) and error messages (I/O ERROR # followed by a location to store the position of the next character to be pro-
number). This location controls which types of messages, if cessed from the instruction address buffer (2720-2729/
any, will be displayed. When the value here is set to 0/$00, $OAA0-$0AA9).
no Kernal messages are displayed. Setting bit 6 to %1 enables
error messages, while setting bit 7 to %1 enables control mes- 160-162 $A0-$A2 TIME
sages. The value here can be set using the Kernal SETMSG Software jiffy clock
routine [$F75C]. The BASIC routine MAIN [$4DB7], which is These three bytes comprise the jiffy clock, a counter main-
responsible for the READY prompt, sets this flag to 128/$80 tained by the operating system. Location 160/$A0 is the high
(control messages only), since BASIC provides its own error byte, 161/$A1 the middle byte, and 162/$A2 the low byte.
messages. When the RUN routine is executed to run a pro- The UDTIM routine [$F5F8], called during each system jiffy
gram, the value here is reset to 0/$00 (no messages). The IRQ interrupt sequence, will increment this counter 60 times
monitor changes the setting to 192/$C0 (all messages). per second. (UDTIM checks and compensates for PAL video
54 55
163 $A3 $A6 166
systems, so these locations are incremented 60 times per sec- 164 $A4 FIRT/BSOUR1
ond regardless of whether interrupts occur at the North Amer- Tape: Half-cycle indicator
ican rate of 60 times per second or the European rate of 50 Serial: Byte received
times per second.) Thus, location 162/$A2 will be incre- When bits are being read from or written to tape, this location
mented every 1/60 second; location 161/$A1 every 1/60 * is used to indicate which half-cycle for the bit is currently be-
256 = 4.27 seconds; and location 160/$A0 every 4.27 * 256 ing received or sent.
= 1092 seconds, or every 18.2 minutes. All three locations
When characters are being received over the serial bus,
(along with the rest of zero page) are reset to 0/$00 during
the reset sequence. The UDTIM routine will also reset the lo- this location is used to assemble received bits into complete
cations to 0/$00 if the value here reaches $4F1AO1, cor- bytes.
responding to 24 hours after the start of the count. The Kernal 165 $A5 CNTDN/COUNT
RDTIM routine [$F65E] can be used to read these locations, Tape: Leader synchronization countdown
and the SETTIM routine [$F665] can be used to change the Serial: Count of bits to send / burst mode byte count
value here. From BASIC, the reserved variables TI and TI$ can
be used to read the values here (TI$ converts the value to During the routines which write blocks of data to tape, this lo-
hours:minutes:seconds format). TI$ can also be used to change cation is used to provide the countdown characters that come
the value here. at the end of each leader segment. The value here is initialized
to 9; it will then be repeatedly written to tape and decremented
Although this timer is easy to use, especially from BASIC until the value reaches zero.
with TI and TI$, it's not particularly accurate for timekeeping When characters are being sent over the serial bus, this
applications. These locations depend on the system IRQ inter- location is used as a countdown of bits to be sent. The value
rupt, which is affected by a number of operations. For ex- here is initialized to 8 for each byte and decremented each
ample, the system interrupt is turned off during loads and time a bit is sent. When bytes are being read from the serial
saves to tape or disk, effectively stopping the clock. The more bus, this location is used to indicate whether an EOI hand-
tape or disk operations you perform, the more inaccurate your shake has been detected. The value is initialized to 0/$00,
clock time becomes. If you need more reliable timekeeping, re- then incremented after the first EOI is received. During high-
fer to the discussion of the CIA chips' time-of-day clocks in speed burst mode loads, this location is used as a count of the
Chapter 8. number of bytes read from the current disk sector.
56 57
167 $A7 $AC-$AD 172-173
block of data will be written to tape and the value here will be 170 $AA RDFLG/RIDATA
reset to 0/$00.
Tape; Read phase flag
RS-232: Assembly byte for received bits
167 $A7 SHCNL/INBIT
Tape: Leader dipole count / block indicator During the routines which read from tape, this location indi-
RS-232: Current bit received cates the current stage of the operation. When the value here
is 0/$00, the reading routine is waiting for the synchroniza-
During the routines which write to tape, this location is used tion countdown characters to be read. Nonzero values less
as one counter in a timing loop to specify the number of lead- than 64/$40 indicate that block countdown characters are be-
er dipoles to be written. When reading from tape, this location ing read. A value of 64/$40 indicates that the first copy of the
is used to indicate which block is being read. data block has been read, while a value of 128/$80 indicates
When characters are being received over the RS-232 inter- that all characters from the first block have been read and the
face, this location holds the most recently received bit. routine is waiting for the second copy.
When characters are being received over the RS-232 inter-
168 $A8 RER/BITCI face, the bits received are shifted into this location until a full
Tape: Half-cycle indicator for writing / error flag for reading byte has been assembled.
RS-232: Count of bits remaining to be received
When bits are being written to tape, this location is used to 171 $AB SHCNH/RIPRTY
indicate which half-cycle of the dipole for the bit is currently Tape: Leader dipole counter / checksum work byte
being written. When characters are being received from tape, RS-232: Received byte parity
this location is used as a flag to indicate an error in the re- During the routines which write to tape, this location is used
ceived byte. as one counter in a timing loop to specify the number of lead-
When characters are being received over the RS-232 inter- er dipoles to be written. During the routines which read from
face, this location is used as a countdown for the number of tape, this location is used for computing the checksum for the
bits to be received for the current character. The value here block being read.
will be initialized from 2581/S0A15 for each character. When characters are being received over the RS-232 inter-
face, this location is used to indicate whether an odd or even
169 $A9 REZ/RINONE number of %1 bits have been received, to determine the parity
Tape: Word marker flag / half-cycle flag of the received bit.
RS-232: Start bit received flag
When characters are being written to tape, this location is used 172-173 $AC-$AD SAL-SAH
to indicate whether a word marker dipole has yet been written Kernal working address pointer
for the current character. When characters are being read from These locations are used as a pointer to the address of the cur-
tape, this location is used to indicate whether the next half- rent byte to be written to tape or saved to disk, or the address
cycle should be a long or short one. where the byte read from tape or from a disk boot sector is to
When characters are being received over the RS-232 inter- be stored. The Kernal has several routines to service this pointer,
face, this location is used to indicate whether a start bit has including one [$ED51] to load this pointer with the operation
been received yet, A nonzero value here indicates that the sys- starting address in 193-194/$C1-$C2, one [$EEC1] to incre-
tem is still waiting for a start bit, while a value of 0/$00 ment the address here, and one [$EEB7] to compare the ad-
means that a start bit has been received. dress here against the operation ending address at 174-175/
$AE-$AR There is also a routine [$F7CC] to retrieve the char-
acter at the pointer address from the bank specified in 198/$C6,
58 59
172-175 $AC-$AF $B6 182
and one [$F7BC] to store the current accumulator contents at 178-179 $B2-$B3 TAPE1
the pointer address in the bank specified in 198/$C6. pointer to cassette buffer
These locations hold the starting address of the 192-byte cas-
172-175 $AC-$AF sette buffer. The value here is initialized to 2816/$0B0O by the
Work area for disk booting Kernal RAMTAS routine, part of the reset sequence. No
The Kernal BOOT-CALL routine [$F890] uses locations Kernal routine changes this default setting. The routines that
172-173/$AC-$AD to hold the address at which the contents read and write data to tape test these locations to insure that
of additional boot sectors are to be stored. Location 174/$AE the address is greater than 512/$0200.
holds the bank number for the additional data. Location 175/
$AF holds the number of disk sectors to be loaded during the 180 $B4 SNSW1/BITTS
boot process. Tape: leader/data flag
RS-232: Count of bits transmitted
174-175 $ AE-$ AF EAL-E AH During routines which read from tape, this location is used to
Kernal address pointer indicate whether the routine is currently waiting for the start
This location is used during the routines which read from or of a data block (indicated by a value of 0/$00 here) or reading
write to tape, or in saving to disk, to hold the ending address data from a block (indicated by a nonzero value here).
for the operation. For loading from disk, this location is used When bytes are being sent over the RS-232 interface, this
as a working pointer to the address where data is stored. After location holds the count of bits sent for the current character.
all bytes have been loaded, the locations will hold the ending
address. (Actually, in all cases the pointer will hold the ad- 181 $B5 DIFF/NXTBIT
dress of the location immediately following the last one in- Tape: Leader completed flag
volved in the operation.) The Kernal SAVF routine [$F53E] RS-232: Next bit to send
initializes these locations with the contents of the X and Y reg- During routines which read from tape, this location is used to
isters when the routine is called. The Kernal provides a routine indicate when the end of a leader segment has been reached.
[$F7C9] to retrieve the character at the pointer address from The value here is set to 0/$00 when the word marker at the
the bank specified in 198/$C6, and one [$F7BF] to store the end of a leader is read.
current accumulator contents at the pointer address in the When bytes are being sent over the RS-232 interface, bit 2
bank specified in 198/$C6. of this location is used to hold the setting of the next bit to be
sent.
176 $BO CMPO
Tape adjustable baseline compensation factor 182 $B6 PDP/RODATA
This location is used during tape routines to indicate whether Tape: Error flag / end of block flag
the current baseline time (the time allotted for a particular RS-232: Character being sent
type of dipole) needs to be slightly increased or decreased. When an error is detected while a character is being read from
This allows the computer to compensate for slight variations tape, this location is set to a nonzero value to indicate that the
in tape speed. character has not been read successfully. During routines
which write to tape, this location is used as a flag to indicate
177 $B1 TEMP when end-of-block processing should be performed.
Working storage for compensation factor computation When bytes are being sent over the RS-232 interface, this
This location is used as a work byte for computing the base- location holds the character being sent. Bits are pulled off one
line compensation factor at 176/$B0. at a time from right to left.
60 61
183 $B'
$co 192
tains a 0/$00, the port bit is set to turn off the power. Thus, here doesn't affect the current system configuration; it only
the cassette motor can't be powered when no button is specifies the bank for load, save, or verify operation data. The
pressed or while this location contains 0/$00. When this loca- Kernal SETBANK routine [$F73F] can be used to set the value
tion is set to any nonzero value, the setting of the port bit is here.
not affected by the IRQ subroutine, so—as long as a button is
pressed—the motor can be turned on and off, changing the 199 $C7 FNBANK
setting of the port bit. Bank where filename for open, save, load, or verify is found
This location holds the bank number in which the filename for
193-194 $C1-$C2 STA the current I/O operation is found. The value here can be set
Kernal address pointer using the Kernal SETBANK routine [$F73F].
These locations are used by the Kernal SAVE routine [$F542]
to hold the starting address of the area of memory to be saved 200-201 $C8-$C9 RIBUF
to disk or tape, The value is loaded from the zero-page pointer Pointer to RS-232 input buffer
specified in the accumulator upon entry to the routine. The value in these locations determines the starting address of
These locations are also used by the Kemal BOOT_CALL the 256-byte RS-232 input buffer—the area where characters
routine. Location 193/$C1 holds the track number and loca- are stored as they are received via the RS-232 interface. The
tion 194/$C2 holds the sector number for the block currently value here is initialized to 3072/S0C00 by the RAMTAS rou-
being read from disk. tine [$E093], part of the reset sequence. This places the input
buffer at its default position, and no system routine changes
195-196 $C3-$C4 TMP2/MEMUSS this setting.
Kernal address pointer
The contents of the X and Y registers upon entry to the Kemal 202-203 $CA-$CB ROBUF
LOAD routine [$F265] are stored here. If the secondary ad- Pointer to RS-232 output buffer
dress that preceded the LOAD was 0/SOO, a relocating load The value in these locations determines the starting address of
was specified, so this address is used as the starting address the 256-byte RS-232 output buffer—the area where characters
for the loaded data. are stored while they await transmission via the RS-232 inter-
These locations are also used as a working pointer in the face. The value here is initialized to 3328/S0D00 by the
routine [$E1FO] to initialize the soft reset vector, RAMTAS routine [$E093], part of the reset sequence. This
places the output buffer at its default position, and no system
197 $C5 DATA routine changes this setting.
Bit read from tape / checksum of block written to tape
During routines which read from tape, this location is used to 204-205 $CC-$CD KEYTAB
indicate the value of the bit most recently read. During Pointer to current keyboard decode table
routines which write to tape, this location is used for working The value in these locations determines the starting address of
storage of the checksum being calculated for the block. the 89-byte area of memory which will be used to decode the
current keyboard matrix code in location 212/$D4. The
198 $C6 BA SCNKEY routine [$C55D], part of the normal IRQ sequence,
Bank where data for save, load, or verify is found checks on the shift-key status (in location 211/$D3) and se-
This location holds the bank number from which data will be lects the proper value from the list of keyboard table pointers
saved by the Kernal SAVE routine or to which data will be at $83u-841/$033E-$0349.
loaded or verified by the Kernal LOAD routine. The value
64 65
206-207 $CE-$CF 5D4 212
66 67
213 $D5 $D8 216
Certain keyscan codes will not normally be recorded here. RUN/STOP-RESTORE sequences, the screen editor initializa-
The codes for the left and right SHIFT keys, the CONTROL tion routine [$C07B] sets this flag according to the position of
key, the Commodore key, and the ALT key—codes 15, 52, 58, the 40/80 DISPLAY key.
61, and 80, respectively—-are normally intercepted during the While it is often useful to check this flag to determine
SCNKEY routine and used to generate the value at 211/SD3. which display is active, it shouldn't be changed to switch ac-
The CAPS LOCK, 40/80 DISPLAY, and RESTORE keys are tive displays. Instead, use the escape sequence (ESC X) or the
not part of the keyscan matrix, and the SHIFT LOCK key is Kernal SWAPPER routine [$FF5F]. There's more to changing
just a switch that has the effect of holding down the left active displays than just toggling the flag bit—the active and
SHIFT key. inactive screen editor variable tables, line link bitmaps, and
tab stop bitmaps must also be exchanged.
213 $D5 LSTX
Last key pressed 216 $D8 GRAPHM
At the end of the SCNKEY routine [$C55D], the value in Mode flag for 40-column screen
212/$D4 is transferred here. This value is then used during This location is used during the screen IRQ routine [$C194] to
the next pass through SCNKEY to determine if the same key determine which display mode is selected for the 40-column
is still being pressed. If so, no additional character code will be (VIC) screen. The value here has no effect on the 80-column
added to the keyboard buffer unless key repeating is enabled. (VDC) screen. When this location contains 0/$00, text mode is
selected. Bits 5-7 control the graphics mode configurations:
214 $D6 CRSW Bit Bit value Mode selected
Input source flag 5 32/$20 bitmapped
This location is used during the screen editor BASIN routine 6 64/$40 split bitmapped/text
7 128/$80 multicolor
[SC29B] to indicate whether the line of input is to come from
the keyboard or from the screen. The default value of 0/S00 More than one of these can be selected at one time. The stan-
selects input from the keyboard, while a nonzero value selects dard graphics modes place the following values here:
input from the screen. The Kernal BASIN routine [$EF06] will Mode Value
set this location to 3/$03 before calling the screen editor rou- GRAPHIC 0 0/$00
tine when screen input is requested. Bit 7 of this location is GRAPHIC 1 32/$20
used as an end-of-input flag; however, this is not handled GRAPHIC 2 96/$60
GRAPHIC 3 160/JAO
properly for input from the screen. See the entry for the screen GRAPHIC 4 224/$E0
editor routine in Chapter 7 for details.
While the standard screen editor interrupt routine is in
$D7 use, the value here determines how the screen mode will be
215 MODE set up. As a result, you cannot directly change the bitmapped
Active screen flag or multicolor mode control bits of the VIC chip, since those
Bit 7 of this flag determines which text screen is considered bits will be set according to the value here. You can turn off
the active display. While the bit is % 1 , the 80-column display the screen-setup portion of the screen editor IRQ routine by
is selected. While the bit is %0, the 40-column display is ac- storing the value 255/$FF here. This gives you direct control
tive. Note that the inactive screen isn't actually turned off; it over the VIC chip register settings, but disables BASIC'S ability
retains whatever display it had when the other screen was se- to change display modes.
lected. However, only the active screen has a "live" cursor,
and all printing is directed there. During the reset and
68 69
217 $D9 $E2-$E3 226-227
starting page of 216/$D8 in the case of the 40-column (VIC) screen, when the window is reset to full screen size, as when
display, or for the starting color memory page value in the CINT screen editor initialization routine is executed. This
2607/$0A2F in the case of the 80-column (VDC) display. location can be assigned a specific column number using the
Since the tables have only 25 valid entries, the screen editor screen editor WINDOW routine [$CA1B], which has a screen
cannot support an output window with more than 25 rows. editor jump table entry at 49197/$C02D. From BASIC, the
WINDOW statement can be used to change the value here.
228 $E4 SCBOT The ESC T sequence will cause the column number for the
Bottom margin of current window current cursor position to be stored here.
The value in this location determines which screen row will be 231 $E7 SCRT
the bottom margin of the current output window. This value
Right margin of current window
should be greater than or equal to the value in location
229/SE5. This location is reset to the maximum column num- The vaiue in this location determines which screen column
ber from location 237/$ED when the window is reset to full will be the right margin of the current output window. This
screen size, as when the CINT screen editor initialization rou- value should be greater than or equal to the value in location
tine is executed. This location can be assigned a specific row 230/$E6. This location is reset to maximum column number
number using the screen editor WINDOW routine [$CA1B], from location 238/$EE when the window is reset to full screen
which has a screen editor jump table entry at 49197/$C02D. size, as when the CINT screen editor initialization routine is
From BASIC, the WINDOW statement can be used to change executed. This location can be assigned a specific column
the value here. The ESC T sequence will cause the row num- number using the screen editor WINDOW routine [$CA1B],
ber for the current cursor position to be stored here. which has a screen editor jump table entry at 49197/$C02D.
From BASIC, the WINDOW statement can be used to change
the value here. The ESC B sequence will cause the column
229 $E5 SCTOP number for the current cursor position to be stored here.
Top margin of current window
The value in this location determines which screen row will be 232 $E8 LSXP
the top row of the current output window. This value must be Cursor row for start of input
less than or equal to the value in location 228/$E4. The value
This location determines the starting row for the logical line of
here is reset to 0/$00, the top row of the screen, when the
input characters to be read by the BASIN routine [$C29B]. Lo-
window is reset to full screen size, as when the CINT screen
cation 235/$EB will hold the row for the end of the input line.
editor initialization routine is executed. This location can be
assigned a specific row number using the screen editor WIN-
DOW routine [$CA1B], which has a screen editor jump table 233 $E9 LSTP
entry at 49197/$CO2D. From BASIC, the WINDOW statement Cursor column for start of input
can be used to change the value here. The ESC T sequence This location determines the starting column for the logical
will cause the row number for the current cursor position to line of input characters to be read by the BASIN routine
be stored here. [$C29B]. Location 2608/$0A30 will hold the column for the
end of the input line.
230 $E6 SCLF
Left margin of current window 234 $EA INDX
Column of last nonspace character on logical line
The value in this location determines which screen column
will be the left margin of the current output window. This The screen editor includes a routine [$CBC3] to find the posi-
value must be less than or equal to the value in location tion of the last nonspace character in the current logical line.
231/SE7. The value here is reset to 0/$00, the left edge of the That routine stores the column number of the character posi-
tion here.
71 73
235 $EB SEE 238
235 $EB TBLX the value in location 230/SE6, the left margin of the output
Cursor row window. Each time a character is printed to the window, the
This location holds the cursor's horizontal position on the value here is incremented, unless the increment would cause
screen. When the cursor is moved onto a new line, the value the value here to exceed the value in location 231/$E7, In that
here is used as an offset into the screen memory line base case, the value here is reset to the left margin value in 230/
starting address tables during the calculation of the starting $E6. The value here is also reset to the left margin value when-
address for the current screen memory line (224-225/ ever a RETURN character (code 13/SOD) or SHIFT-RETURN
$EO-$E1) and the starting address for the current color mem- (code 141/$8D) is printed.
ory line (226-227/$E2-$E3). When the output window is The PLOT routine [$CC6A] can be used to set or read the
cieared or the cursor is moved to the home position, the value value here, but the coordinates supplied to PLOT are relative
here will be reset to the value in location 229/$E5, the top to the current left margin. That is, the horizontal offset placed
margin of the window. The value here is incremented when- here when PLOT is used will be the horizontal coordinate
ever the cursor wraps around from the right margin of the specified in the PLOT call plus the current left margin value in
window back to the left—or whenever a RETURN character 230/$E6, and the coordinate value returned by PLOT will be
(code 13/$0D), SHIFT-RETURN (code 141/$8D), or cursor- the value here less the current left margin value in 230/SE6.
down (code 17/ $11) is printed—unless the increment would
cause the value here to exceed the bottom margin value in 237 $ED LINES
228/$E4. The action taken in that case depends on whether Maximum number of rows allowed in output window
the scrolling flag (248/$F8) is set to allow new lines to be The value here determines the maximum bottom row for the
scrolled onto the screen. If so, the value here remains un- output window. The current bottom row number is specified
changed and a new line is opened at the bottom of the win- in location 228/$E4. When the window is reset to full screen
dow. If scrolling is not allowed, the value here is reset to the size by printing two {HOME} characters (code 19/$13) in se-
value in 229/$E5 to wrap the cursor to the top of the window. quence (or by directly calling the screen editor window reset
The PLOT routine [$CC6A] can be used to set or read the routine [$CA24]), location 228/$E4 will be reset to the value
value here, but the vertical coordinate used by PLOT is rela- here. This location is set to 24/$18 during the CINT screen
tive to the current top margin. That is, the vertical offset editor initialization routine, which establishes the default max-
placed here when PLOT is used will be the vertical coordinate imum of 25 horizontal rows of characters in the output win-
specified in the PLOT call plus the current top margin value in dow (remember that row numbering begins at zero). No
235/$E5, and the coordinate value returned by PLOT will be system routine changes this setting, but you can reduce the
the value here less the current top margin value in 229/$E5. value here to restrict the maximum height of the output win-
dow. However, you should not increase the value above the
236 $EC PNTR default setting, since the screen editor printing routines will
Position of cursor within current physical line not properly support a window more than 25 lines tall.
This location holds the cursor's horizontal position on the
screen. The value here is used as an offset from the starting 238 $EE COLUMNS
address of the current screen memory line (224-225/$E0-$El) Maximum number of columns allowed per row
to determine the screen memory position of the current char- The value here determines the maximum right margin column
acter, and as an offset from the starting address of the current for the output window. The current right margin column num-
color memory line (226-227/$E2-$E3) to determine the color ber is specified in location 231/$E7. When the window is reset
memory position of the current character. to full screen size by printing two {HOME} characters (code
When the output window is cleared or when the cursor is 19/$13) in sequence (or by directly calling the screen editor
moved to the home position, the value here will be reset to window reset routine [$CA24]), location 231/$E7 will be reset
74 75
239 $EF $F1 241
to the value here. During the CINT screen editor initialization the discussion of the VIC chip in Chapter 8 for details. For the
routine, this location is set to 39/$27 if the 40-column (VIC) 80-column (VDC) display, the lower four bits also hold the
display is the default, or to 79/$4F if the 80-column (VDC) color value, but the relationship of values to colors is different
display is the default. This establishes the default widths of from that for the VIC chip. Refer to the discussion of the VDC
the respective displays (remember that column numbering be- in Chapter 8 for more information.
gins at zero). No system routines change these settings, but When the VDC display is active, the upper four bits of
you can reduce the value here to restrict the maximum width this location hold the attribute value for the next character to
of the output window. However, you should not increase the be printed. Refer to the discussion of the VDC chip in Chapter
value above the default settings, since the screen editor print- 8 for more information on attributes. Bit 4 determines whether
ing routines will not properly support windows wider than the the character will flash. Printing character code 15/$0F will set
respective defaults. bit 4 to % 1 , which specifies a flashing character. Printing char-
acter code 143/$8F resets bit 4 to %0, which turns off the
239 $EF DATAX flashing attribute. Bit 5 determines whether the character will
Character to print be underlined. Printing character code 2/$02 will set bit 5 to
This location is used during the screen editor printing routines % 1 , which specifies an underlined character. Printing charac-
to hold the character code (not the screen code) for the charac- ter code 130/$82 resets bit 5 to %0, which turns off the un-
ter to be printed. derlining attribute. Bit 6 could be used to determine whether
the character is reversed. Setting the bit to %1 specifies a re-
240 $F0 LSTCHR versed image of the character pattern, and resetting the bit to
Last character printed %0 specifies a normal character. However, the 128's screen
This location is used during the screen editor printing routines editor does not make use of this feature. Instead, each stan-
to hold the character code for the previous character printed. dard character set contains both normal and reversed character
After each character is printed, the code for that character is patterns and reversed characters are obtained by selecting the
transferred here from location 239/$EF. The value is used to reversed character pattern. Bit 7 determines which of the two
detect when certain key sequences have been printed, such as character sets will be used. When the bit is %0, the first
the escape (ESC) sequences and the HOME HOME sequence (uppercase/graphics) set is selected, while setting the bit to
%1 selects the second (lowercase/graphics) set. Thus, the
to reset the output window margins. One shortcut to printing VDC allows both character sets to be used on the same dis-
an escape sequence is to set this location to 27/$lB (the code play. When the VDC display is active, printing character code
for the ESC character), then call the screen BSOUT routine 14/$0E sets this bit to % 1 , and printing character code
[$C00C] with the accumulator holding the second character of 142/$8E resets the bit to %0. If character set switching with
the escape sequence. the SHIFT-Commodore key combination is allowed, then that
combination will toggle the value of this bit.
241 $F1 COLOR
Attribute of current character The CINT screen editor initialization routine will set this
The value in this location determines the color (and attribute location to 13/$0D if the VIC screen is the default display, or
for the VDC display) that will be used for the next character to 7/$07 if the VDC screen is the default. This selects light
printed to the output window. When the screen code for the green characters for the VIC display or light cyan characters
character is placed in screen memory, the value here will be with no special attributes for the VDC display. The color value
placed in the corresponding position in color memory. When in the lower four bits can be changed by printing any of the
the 40-column (VIC) screen is the active display, only the 16 color change characters. Refer to Appendix C for a list of
lower four bits of this location are meaningful. Those bits will character code values.
hold the VIC color code (0-15) for the character position, See
76 77
242 $F2 $F6 246
242 $F2 TCOLOR location is reset to zero each time a carriage return character
(code 13/$0D) or shifted return (code 141/$8D) is printed to
Temporary storage for attribute byte end the logical line. This location can also be reset to zero to dis-
This location is used to temporarily preserve the value from able insert mode with either the ESC O or ESC ESC sequences.
241/$F1 during screen editor routines that insert or delete
characters or scroll screen lines. 245 $F5 INSRT
Number of pending inserts
243 $F3 RVS
Reverse mode flag This location holds the number of character positions which
have been inserted in the current logical line. This is signifi-
The value in this location determines whether reverse mode is
cant because insert mode is normally active for inserted char-
active. Reverse mode is active whenever this location contains acter positions. Insert mode is similar to quote mode—cursor
a nonzero value. In this case, bit 7 will be set to %1 in each movement and color change characters are deferred—except
screen code placed in screen memory by the BSOUT screen that the insert key is not deferred in insert mode and the de-
printing routine. This effectively converts screen codes lete key (INST/DEL) is deferred. Insert mode is active when-
0-127/$00-$7F to codes 128-255/$80-$FF. In the default ever this location contains a nonzero value. The value here is
character sets, character patterns in the upper half of each set incremented each time a blank character position is inserted in
are the reverse image of corresponding patterns in the lower the current line, and decremented each time a character is
half. The value here is initialized to 0/$00 (reverse mode off) typed in one of the inserted positions. This location is initial-
by the CINT screen editor initialization routine. This location ized to 0/$00 (insert mode off) by the CINT screen editor ini-
is set to 128/S80 when the reverse-on character (code 18/$12) tialization routine. It is also reset to zero each time a carriage
is printed, and reset to 0/$00 when the reverse-off character return character (code 13/$0D) or shifted return (code
(code 146/$92) is printed. The value here is also reset to zero 141/$8D) is printed to end the line. This location can also be
each time a carriage return character (code 13/$0D) or shifted reset to zero to disable insert mode with either the ESC O or
return (code 141/$8D) is printed to end the line. This location ESC ESC sequences.
can also be reset to zero to disable reverse mode with either
the ESC O or ESC ESC sequences. 246 $F6 INSFLG
Autoinsert mode flag
244 $F4 9TSW Bit 7 of this location determines whether the autoinsert feature
Quote mode flag is active. When the bit is % 1 , autoinsert mode is active, and a
This value in this location determines whether quote mode is space is inserted following each character printed to the
active. Quote mode will be in effect whenever this location screen. If the bit is %0, autoinsert mode is disabled. In this
contains a nonzero value. In this case, cursor movement keys, case, the cursor simply moves to the next character position
CONTROL key combinations, Commodore-number key (color after each character is printed. This location is initialized to
change) combinations, and the insert key (SHIFT-INST/DEL) 0/$00 (autoinsert mode off) during the CINT screen editor ini-
are deferred—they appear as reverse characters within the cur- tialization routine. It is also reset to zero by the BASIC sub-
rent screen line instead of having any direct effect on the routine that sets flag values when a RUN statement is
screen display. The value here is initialized to 0/$00 (quote executed [$5A81]. This location is set to 255/SFF (which sets
mode off) by the CINT screen editor initialization routine. The bit 7 to %1) when the ESC A sequence is printed. It can be re-
value here is exclusive-ORed with l/$01 each time a quote set to 0/$00 with the ESC C sequence.
character (code 34/$22) is printed. Thus, quote mode will nor-
mally be on after an odd number of quotes (1, 3, and so on)
and off after an even number of quotes (2, 4, and so on). This
79
78
247 $F7 $FA 250
247 $F7 LOCKS cursor will wrap around to the top screen line. This bit can be
Case switching / scroll pause control flag set to %1 with the ESC M sequence, and reset to %0 with ESC
Bit 7 of this location determines whether the SHIFT-Commo- L.
dore key combination can be used to switch character sets. If Bit 6 of this location controls whether physical screen
this bit is %0, the SCNKEY routine [$C55D] will switch char- lines can be linked together to form logical lines. For example,
acter sets whenever the SHIFT-Commodore combination is de- BASIC allows logical lines up to 160 characters long. If this bit
tected. Setting this bit to %1 disables character set switching is %0, linking is allowed. The line link bitmap at 862-865/
with SHIFT-Commodore. However, you can still change char- $035E-$0361 will indicate which physical lines are part of
acter sets by printing character 14/$0E for the lowercase/ longer logical lines. Setting this bit to %1 disables line linking,
uppercase set, or character 142/$8E for the uppercase/ in which case no logical line can be more than one physical
graphics set. There is no provision for preventing character set line long. This location is initialized to 0/$00 (linking enabled)
switching using the character codes. This location is initialized during the CINT screen editor initialization routine, and no
to 0/$00 (switching enabled) by the CINT screen editor initial- system routine changes the setting of this bit. Since the screen
ization routine. The bit can be set to %1 by printing character editor doesn't provide a character code or escape sequence for
code 11/$OB, and reset to %0 by printing character code changing this bit, you must change the value here directly if
12/$0C. (Note that this is a change from earlier Commodore you wish to make use of the linking disable feature.
models, where character 8/$08 disabled switching and charac-
ter 9/$09 reenabled switching.) 249 $F9 BEEPER
Bit 6 of this location controls whether the NO SCROLL Bell enable flag
key or CONTROL-S key combination can be used to pause Bit 7 of this location controls whether or not a tone is pro-
output to the screen. If this bit is %0, NO SCROLL or CON- duced when character code 7, the {BELL} character, is printed.
TROL-S will pause printing to the screen until another key is If the bit is %0, then a tone is produced. Setting the bit to %1
pressed. Setting this bit to %1 prevents pausing, so that nei- prevents the tone. The location is tested during the screen
ther NO SCROLL or CONTROL-S will have any effect on BSOUT subroutine that handles character 7 [$C98E], The loca-
screen output. (The Commodore key can still be used to slow tion is initialized to 0/$00 (bell enabled) during the CINT
down printing.) This location is initialized to 0/$00 (pause en- screen editor initialization routine. The flag bit can be set to
abled), and no system routine changes the setting of this bit. %1 using the ESC H sequence, and reset to %0 with ESC G.
Since the screen editor doesn't provide any character code or
escape sequence for disabling the pause feature, you must 250 $FA Unused
change the value here directly if you wish to make use of the
pause disable feature. This location is unused in the sense that it is not intentionally
altered by any 128 Kernal or BASIC routine. However, a bug
in the screen editor CINT [$C07Bj and SWAPPER [$CD2E]
248 $P8 SCROLL routines causes this location to be overwritten whenever those
Scroll/link control flag routines are executed. Because those routines are called during
Bit 7 of this location is tested during the screen editor cursor the RUN/STOP-RESTORE sequence, any value you place in
movement routines to determine whether a new line will be this location will be overwritten any time you press
scrolled onto the output window after printing on the current RUN/ STOP-RESTORE, as well as whenever you switch
bottom line. If the bit is %0, a new blank line will be opened screens. Thus, if you use this location in your programs it
at the bottom of the screen (and the top line will be scrolled should be only as temporary working storage, not for impor-
off the screen) after printing on the bottom line. Setting the bit tant values you might want preserved in the cases mentioned
to %1 prevents scrolling; after printing on the bottom line, the above.
80 81
251-254 $FB-$FE $00FF-$010A 255-266
251-254 $FB-$FE Unused the actual address in page 1.) When a byte of data is pushed
(added) onto the stack, the stack pointer register is automati-
These locations are unused by any 128 ROM routines, and are cally decremented to point to the next available address. When
thus available for use in your BASIC and machine language a byte is pulled (removed) from the stack, the register is auto-
programs. This area is not affected by RUN/STOP-RESTORE, matically incremented. The value is not actually deleted, but
but remember that all zero-page locations, including these, are incrementing the stack pointer will cause the next byte pushed
cleared to zero during a reset (unless the RUN/STOP key is onto the stack to overwrite the old value. The RESET routine
held down during the reset; see the reset routine [$E000] for [$EO00] begins by resetting the stack pointer to 255/$FF, effec-
details). tively emptying the stack.
In addition to the stack's use for processor address infor-
255 $FF mation, BASIC uses it to hold intermediate values during ex-
This location is used as part of the assembly area for character pression evaluation. In earlier Commodore computers, the
strings representing the digits of numeric values. Refer to the system stack was also used to hold information for BASIC
next section for details. statements such as GOSUB and FOR that loop back to another
line. Since every FOR statement requires 18 bytes of stack
Page 1: System Stack space, and every GOSUB or DO requires 5 bytes, only a lim-
ited amount of nesting would be possible before all system
256-511/$0100-$01FF stack space was exhausted. BASIC 7.0 maintains a separate
This page is the system stack, the area where the 8502 stack at 2048-2559/$0800-$09FF for FOR, GOSUB, and DO.
microprocessor stores information such as the return addresses This allows BASIC 7.0 to use more deeply nested FOR-NEXT
and DO-LOOP loops and more levels of subroutines—and
for interrupts and subroutine calls. Some microprocessors hence more complex programs. See Chapter 3 for details of
allow longer stacks or allow the stack to be located at various the BASIC stack.
places in memory, but 6502-family microprocessors like the
128's 8502 have only one 256-byte stack, and it's always page The 8502 normally uses all of page 1 as stack space, but
1. Unlike other Commodore computers, however, the 128 has BASIC manipulates the stack pointer to allow the 128 to use
the ability to make the 8502 see page 1 anywhere in memory. portions of this area in other ways. The BASIC cold-start rou-
The MMU chip has a feature which allows the processor to tine [$4023] resets the stack pointer to 251/$FB, so locations
exchange page 1 with another page, so that all references to 508-511/$01FC-$01FF are not used by BASIC. The CLR rou-
page 1 (including the processor's stack manipulations) are di- tine [$51F8], also part of NEW and RUN, resets the stack
rected to the alternate page, and references to addresses in the pointer to 250/$FA. BASIC limits the stack to 201 bytes, halt-
alternate page are directed to page 1. See the discussion of the ing with an error if all BASIC stack space is exhausted. The
MMU in Chapter 8 for details. The 128 does not normally portions of this page used for purposes other than the stack
behave like any other part of RAM.
make use of this feature; page 1 is normally seen at the true
page 1 locations here.
The storage of data in the stack is controlled by a register 255-266 $00FF-$010A
in the microprocessor called the stack pointer, which serves as Assembly area for numeric value strings
an index to the next available address in the stack. The stack The routine [S8E42] which generates a character string repre-
is filled from top to bottom—from location 511/$01FF down- senting the floating-point value in FAC1 uses this area to as-
ward to 256/$100. When no data is in the stack, the stack semble the characters for the digits of the value. The first
pointer contains 255/$FF, indicating that 511/$01FF is the character of the string will be either a space (for a positive
first available location. (The pointer is a one-byte index, to value in FAC1) or a minus sign (for a negative value). When
which the microprocessor automatically adds 256/$0100 to get numeric values are being printed, the string is assembled start-
82 83
256-268 $0100-$010C $0200-$02A0 512-672
ing at 256/$0100. However, when the string of characters for 291-310 $0123-$136
a line number is assembled, it starts at 255/$00FF. Because PRINT USING work area
the routine to add the characters here to the string pool as- The PRINT USING routine [$9520] uses this area to hold
sumes that the string starts at 256/$0100, this will cause the information about the way the output string is to be
leading space to be omitted for line number values. formatted.
256-268 $0100-$010C 294 $0126
Assembly area for disk boot command Command type indicator for PLAY processing
The Kernal BOOT_CALL routine [$F890] uses this area to as- This location is used during the PLAY statement routine
semble the block read command string to be sent to the drive. [$6DE1] to hold a value indicating which PLAY command (V,
The default command string i s U l : 1 3 0 0 1 00 (held in reverse O, T, X, or U) is currently being processed.
order) to read the contents of sector 0 of track 1, the first boot
sector. If more boot sectors follow, the track and sector param- 311-507 $0137-$01FB
eters will be updated to form the commands to read the addi- Stack space used by BASIC
tional sectors. This is the portion of the stack used while BASIC is active.
The BASIC cold-start routine initializes the stack pointer to
256-317 $O1OO-$O13D 251/$FB, but any subsequent NEW will reinitialize it to
Tape error log 250/$FA. Thus, locations 508-511/$01FC-$01FF (and, after
The Kernal routine which stores blocks of data on tape writes the first NEW, also 5O7/$1FB) are unused and available for
two identical copies of the data. That way, if errors are de- your own programming. BASIC requires that at least 44 bytes
tected when the first copy is read back in, it may be possible be available in the stack at the start of any expression evalua-
to correct that error from the second block. Whenever the rou- tion. The stack pointer is tested during the main expression
tine to load a block of data from tape [$EAEB] detects an error evaluation routine [$77EF]; if it is less than 99/$63, a FOR-
in a byte read from the first copy of the block, it stores the ad- MULA TOO COMPLEX error occurs. (This is a change from
dress of the erroneous byte in this area. Location 158/$9E Commodore 64 BASIC, where the same situation would result
serves as an index to the next available address slot. This area in an OUT OF MEMORY error.)
is sufficient to hold 31 error addresses, so a load error occurs
on the first pass only if more than 31 errors are recorded.
When the second copy of the block is read, any address for Input Buffer
which an error was recorded on the first pass will be loaded
with the corresponding byte from the second copy (unless an 512-672 $0200-$O2AO BUF
error was also detected for that same address in the second BASIC and monitor input buffer
copy; in that case, a load error occurs). This 161-byte area is used to hold input for both BASIC and
the monitor. The BASIC input routine [$4F93] allows logical
272-290 $0110-$0122 program lines up to 160 characters long to be entered. A byte
DOS command work area with the value 0/$00 is added following the last character of
The routine [$A3C3] to assemble command strings for the var- the input. If the line starts with a line number, the line here is
ious BASIC DOS support commands such as HEADER, COPY, tokenized and transferred to the BASIC program text area. An
and SCRATCH uses this area to hold information about the immediate mode line (one with no line number) is tokenized
type of command string to assemble. and then executed from the buffer. This buffer is also used to
hold input characters for the GET, GET#, GETKEY, INPUT,
and INPUT* statements, which is why those statements are
85
673 $O2A1 $02AF-$02BD 687-701
not allowed in immediate mode. The monitor main loop The routine reads and stashes the current MMU configu-
[$B08B] accepts command strings up to 159 characters long, ration register setting, then uses the value in the X register
and also adds a zero byte following the last character of input upon entry as the new configuration register setting. Next, the
to mark the end of the command. contents of the location specified by the address in the pointer
plus the offset in the Y register are loaded into the accumu-
673 $O2A1 Unused lator. The MMU configuration register is restored to its original
The BASIC and monitor input routines restrict the length of an value before exiting.
input line to 160 characters plus a zero byte to mark the end This routine is normally called via its related Kernal rou-
of input in the buffer, for a maximum of 161 bytes. Thus, this tine at 63440/$F7D0, which has a jump table entry at 65396/
location will never be used for input, and is available for other $FF74. When calling via the Kernal routine, the accumulator
uses. should contain the zero-page pointer address; the Kernal rou-
tine stores the accumulator value upon entry in 682/$02AA,
performing that setup step for you. The X register should con-
Common Indirect Routines tain a bank number (0-15) rather than an MMU configuration
The routines at 674-763/$02A2-$02FB are copied here from register setting value, since the Kernal routine also performs
Kernal ROM at 63488-63577/$F800-$F859 by the routine at the chore of converting the bank number into a configuration
57549/$E0CD, part of the reset sequence. The routines are register value,
placed here in page 2 because this is part of the IK block of
memory that is visible in all banks. These routines are the key 687-701 $02AF-$02BD STASH
to the operation of the 128—they make the memory banking
system possible by allowing a routine in one bank configura- Stores a value in any bank
tion to access data or call routines in another configuration. This routine stores the contents of the accumulator at a speci-
For example, these routines allow BASIC ROM routines to use fied location in any bank. Before calling this routine, you must
different blocks of RAM for program text and variables, and to set up a two-byte pointer in zero page to hold the address of
see program text in areas of RAM that lie at the same ad- the target location, then store the one-byte address of the
dresses as BASIC ROM itself. These routines are so integral to 2ero-page pointer in location 697/$02B9. You can use the Y
the successful operation of the 128 that the system will proba- register to specify an offset from the pointer address for the
bly crash almost immediately if the routines are accidentally target address. (If no offset is desired, be sure that the Y regis-
changed or overwritten. ter contains 0/$00.) The X register should contain the MMU
configuration register setting value which will establish a
memory configuration in which the target location is visible.
674-686 $02A2-$02AE FETCH The routine reads and stashes the current MMU configu-
Retrieves a value from any bank ration register setting, then uses the value in the X register
This routine loads the accumulator value with the contents of upon entry as the new configuration register setting. Next, the
a specified location in any bank. To use this routine, you must contents of the accumulator upon entry are stored in the loca-
set up a two-byte pointer in zero page to hold the address of tion specified by the address in the pointer plus the offset in
the target location, then store the one-byte address of the the Y register. The MMU configuration register is restored to
zero-page pointer in location 682/$02AA. You can use the Y its original value before exiting.
register to specify an offset from the pointer address for the This routine is normally called via its related Kernal rou-
target location. (If no offset is desired, be sure that the Y regis- tine at 63450/$F7DA, which has a jump table entry at
ter contains 0/$00.) The X register should contain the MMU 65399/$FF77. When calling via the Kernal routine, the X reg-
configuration register setting value which will establish a ister should instead contain a bank number (0-15), since the
memory configuration in which the target location is visible.
86
1 87
702-716 $02BE-$02CC I $02E3-$02FB 739-763
Kernal routine performs the chore of converting the bank Before calling the routine you must load location 2/$02
number into an MMU configuration register setting value. with the bank number (0-15) of the target routine and loca-
tions 3-4/$03-$04 with the address of the target routine. In
702-716 $02BE-$02CC CMPARE contrast to the usual low-byte/high-byte format, location
Compares accumulator contents against a value from any bank 3/$03 should be loaded with the high byte of the address and
This routine compares the accumulator value against the con- location 4/$04 with the low byte. Location 5/$05 should be
tents of a specified location in any bank. Before calling this loaded with the value you want in the status register when the
routine, you must set up a two-byte pointer in zero page to target routine is called (use 0/$00 if you don't want any status
hold the address of the target location, then store the one-byte register bits set). Optionally, you can also load locations
address of the zero-page pointer in location 712/$02C8. You 6-8/$06-$08 with any values you wish the accumulator, X
can use the Y register to specify an offset from the pointer ad- register, and Y register, respectively, to have when the target
dress for the target address, (If no offset is desired, be sure routine is called.
that the Y register contains 0/$00.) The X register should con- The routine calls JMPFAR to call the subroutine addressed
tain the MMU configuration register setting value which will in locations 3-4 in the bank specified in location 2 and with
establish a memory configuration in which the target location the status register value specified in location 5 and processor
is visible. register values from locations 6-8. Upon return from the target
This routine reads and stashes the current MMU configu- routine, the exit values of the accumulator, X register, and Y
ration register setting, then uses the value in the X register register are stored in location 6-8/$06-$08, respectively. The
upon entry as the new configuration register setting. Next, the value of the status register upon exit from the target routine is
value in the accumulator upon entry is compared against the stored in location 5/$05, and the exit value of the processor
contents of the location specified by the address in the pointer stack pointer is recorded in location 9/$09. Finally, the routine
plus the offset in the Y register. The MMU configuration regis- switches the system to the bank 15 configuration before re-
ter is restored to its original value before exiting. The status turning to the calling routine.
register value will reflect the result of the comparison.
This routine is normally called via its related Kernal rou- 739-763 $02E3-$02FB JMPFAR
tine at 63459/$F7E3, which has a jump table entry at 65402/ Jumps to a routine in any bank
$FF7A. When calling via the Kernal routine, the X register (This routine has a Kernal jump table entry at 65393/SFF71.)
should instead contain a bank number (0-15), since that rou- The routine here will jump to a routine at any address in any
tine performs the chore of converting the bank number into an standard bank configuration. Before calling the routine you
MMU configuration register setting value. must load location 2/$02 with the bank number (0-15) of the
target routine and locations 3-4/$03-$04 with the address of
717-738 $02CD-$02E2 JSRFAR the target routine. In contrast to the usual low-byte/high-byte
Calls a subroutine in any bank format, location 3/$03 should be loaded with the high byte of
(This routine has a Kernal jump table entry at 65390/$FF6E.) the address and location 4/$04 with the low byte. Location
The routine here will jump to a subroutine at any address in 5/$05 should be loaded with the value you want in the status
any standard bank configuration. Upon completion of the tar- register when the target routine is called (use 0/$00 if you
get routine, control is returned to the routine which called don't want any status register bits set). Optionally, you can
JSRFAR, just like a JSR. However, this routine leaves the sys- also load locations 6-8/$06-$08 with any values you wish the
tem in the bank 15 configuration, so a routine that uses accumulator, X register, and Y register, respectively, to have
JSRFAR must be located in an area of memory visible in the when the target routine is called. The routine pushes the ad-
bank 15 configuration for JSRFAR to properly return to the dress and status register values onto the stack, converts the
calling routine.
88
1 bank number value to a configuration register value, stores
89
764-765 $02FC-$02FD $0304-$0305 772-773
that value in the MMU configuration register, loads the pro- BASIC Indirect Vectors
cessor registers from locations 6-8, and executes an RTI in- The next nine vectors, 768-785/$0300-$0311, are used in
struction, which causes the processor to retrieve status register BASIC statement processing routines. The default values for
and address values from the stack and resume processing at these vectors are copied from a table at 16999-17016/
the specified address. $4267-$4278 in BASIC ROM by the BASIC vector initializa-
tion routine [$4251], part of the cold-start sequence. Thus,
unlike the Kernal indirect vectors, the BASIC vectors are not
Indirect Vectors affected by the RUN/STOP-RESTORE sequence. Any changes
The next 66 locations are indirect vectors for a variety of you make to the vectors will remain in effect until the next
BASIC, Kernal, and screen editor routines. An indirect vector cold start of BASIC, as during a reset.
is a pair of locations that hold an address for an indirect jump
instruction, such as JMP ($0300). The target address of the 768-769 $0300-90301 IERROR
JMP will be determined by the value in the specified indirect Indirect vector for BASIC error handling routine
vector. Having ROM routines jump through indirect vectors In BASIC ROM, the jump through this vector is taken at the
greatly increases the flexibility of the computer. Even though it beginning of the error handling routine (ERROR [$4D3C]). At
isn't possible to change a routine in ROM, it's possible to add the point the jump is taken, the X register will contain the cur-
to or modify a routine that has an indirect vector by redirect- rent BASIC error number (0-41, or 128 to print READY) and
ing the vector to a RAM-based routine. the accumulator will hold the last character read from program
text. The default target address of the vector is 19775/$4D3F,
764-765 $02FC-$02FD ESC_FN_VEC which simply reenters the error handling routine at the point
Indirect vector in extended function execution routine immediately following the jump. You can redirect this vector
The indirect jump through this vector is taken in the extended to change the way BASIC handles errors.
function handling subroutine when a two-byte extended func- In addition to modifying error handling, you can also use
tion token is found for which the second byte is greater than this vector to provide an alternate method of adding com-
the largest standard extended function token (10/$0A). When mands to BASIC.
the jump is taken, the accumulator will hold the out-of-range
token value and the status register carry bit will be set. If carry 770-771 $0302-$0303 IMAIN
is not clear upon return from the jump, a SYNTAX error mes- Indirect vector in main BASIC loop
sage will be generated. The vector normally holds 19576/
The jump through this indirect vector is taken in the main
$4C78, the address of the instruction following the call to this
BASIC direct mode routine [$4DB7] at the point immediately
vector. This doesn't change the carry setting, so out-of-range
after the READY prompt has been printed and the mode flag
extended function tokens normally result in an error message.
(127/$7F) has been set for immediate mode. The vector nor-
If you add new functions to BASIC, you'll need to change this
mally holds 19910/$4DC6, the address of the instruction im-
vector to point to the routine which executes your new func- mediately following the indirect jump. You can redirect this
tion. See Chapter 5 for an example. vector to a routine of your own if you wish to change the be-
havior of BASIC'S immediate mode.
766-767 $02FE-$02FF BNKVEC
Reserved indirect vector 772-773 $0304-$0305 ICRNCH
These two locations are not used by system ROM routines. Indirect vector in BASIC tokenization routine
Commodore literature indicates that they are reserved for use
The jump through this indirect vector is taken at the begin-
as an indirect vector for function ROM routines.
ning of the CRUNCH routine [$430A], which is responsible
for converting lines of input text into tokenized program lines.
90 91
774-775 $0306-$0307 $0310-$0311 784-785
The vector normally holds 17165/S430D, the address of the lowing the jump. Thus, the jump normally has no effect. If
instruction immediately following the indirect jump. You can you want to add extended tokens to BASIC, you should redi-
redirect this vector to a routine of your own if you wish to rect this vector to your routine to tokenize the new keywords.
change the way program lines are tokenized. The routine should compare the text pointed to by 61-62/
$3D-$3E with the target keyword. If a match is found, your
774-775 $0306-$0307 IQPLOP routine should return with the second byte of the two-byte ex-
Indirect vector in BASIC detokenization routine tended token in the accumulator. The X register should be set
The jump through this indirect vector is taken in the QPLOP to indicate whether the keyword is a statement or a function.
routine [$5123] at the point where the accumulator contains X should be set to 0/$00 for a function, in which case the first
the next character to be listed from the program line. The vec- byte will be 206/$CE, or to 255/$FF for a statement, in which
tor normally holds 20817/S5151, the address of the instruc- case the first byte will be 254/$FE. The Y register should con-
tion immediately following the indirect jump. You can redirect tain the length of the filename. Finally, you should make sure
this vector to a routine of your own if you wish to change the that the carry bit is clear upon exit so that your new token will
way program lines are listed. be properly processed.
the jump through this vector is taken. If your routine does not
lator will hold the second byte of the extended token and the jump to the standard IRQ handler, it must exit by jumping to
carry bit will be set. If the carry bit is not clear upon return, a the common IRQ exit routine at 65331/$FF33.
SYNTAX error will be generated. The vector normally holds
19369/$4BA9, the address of the instruction immediately fol- 790-791 $0316-$0317 IBRK
lowing the indirect jump. Thus, the out-of-range token will
normally cause an error. If you add new extended-token state- Indirect vector to BRK instruction handling
ments to BASIC, you should change this vector to point to the When an IRQ interrupt occurs or a BRK instruction is exe-
address of the routine which executes the new statement. See cuted, a jump is automatically taken through the processor
Chapter 5 for an example. IRQ vector at 65534/$FFFE to the handling routine at 65303/
$FF17. That routine stores the accumulator, X and Y register,
786-787 $0312-$0313 Unused and bank configuration values on the stack, then checks
whether the routine was called as the result of an IRQ or a
These two locations are not used for any system vector, and BRK. If the execution of a BRK was responsible, a jump is
are thus available for your programming. For example, you taken through this indirect vector. The vector normally holds
could use these locations to set up an indirect vector in one of 45059/$B003, the address of the BRK entry into the machine
your own programs, or to store the original value when language monitor. You can redirect this vector to a routine of
changing one of the other vectors. your own if you want some other handling of BRK
instructions.
Kernal Indirect Vectors 792-793 $0318-$0319 INMI
The next 16 vectors, 788-819/$0314-$0333, are initialized
from a table at 57459-57490/$E073-$E092 in Kemal ROM by Indirect vector to NMI interrupt handling routine
the RESTOR routine [$E056]. The RESTOR routine is called When an NMI interrupt occurs, a jump is automatically taken
during both the reset and RUN/STOP-RESTORE sequences, through the processor NMI vector at 65530/$FFFA to the NMI
so either of those will reinitialize the vectors. The values in handling routine at 65285/$FF05. That routine stores the ac-
this vector table can be read or modified using the Kernal cumulator, X and Y register, and bank configuration values on
VECTOR routine [$E05BJ. the stack, then configures the system for bank 15 and takes a
jump through this indirect vector. The vector normally holds
788-789 $0314-$03l5 IIR9 64064/$FA40, the address of the standard system NMI service
Indirect vector to IRQ interrupt handling routine routine. You can redirect this vector to a routine of your own
When an IRQ interrupt occurs or a BRK instruction is exe- to add custom steps to the NMI process. However, your rou-
cuted, a jump is automatically taken through the processor tine must be in an area of memory visible in bank 15, since
IRQ vector at 65534/$FFFE to the handling routine at 65303/ that is how memory will be configured when the jump is
$FF17. That routine stores the accumulator, X and Y register, taken. If your routine does not jump to the standard NMI han-
and bank configuration values on the stack, then checks dler, it must exit by jumping to the common IRQ exit routine
whether the routine was called as the result of an IRQ or a at65331/$FF33.
BRK. If an IRQ was responsible, a jump is taken through this
indirect vector. The vector normally holds 64101/$FA65, the 794-795 $031A-$031B IOPEN
address of the standard system IRQ routine. You can redirect Indirect vector to Kernal OPEN routine
this vector to a routine of your own to add custom steps to the This vector is the normal link between the Kernal jump table
IRQ process. However, your target routine must be visible in entry at 65472/$FFC0 and the OPEN routine at 61373/
bank 15, since that is how memory will be configured when $EFBD, You can redirect this vector to a routine of your own if
you wish to modify the behavior of OPEN.
95
796-797
796-797 $031C-$031D
$O31C-$O31D
ICLOSE
I $032E-$032F
Indirect vector to Kernal CLOSE routine Indirect vector to Kernal BSOUT routine
This vector is the normal link between the Kernal jump table This vector is the normal link between the Kernal jump table
entry at 65475/$FFC3 and the CLOSE routine at 61832/ entry at 65490/$FFD2 and the BSOUT routine at 61305/
$F188. You can redirect this vector to a routine of your own if $EF79. You can redirect this vector to a routine of your own if
you wish to modify the behavior of CLOSE. When the jump is you wish to modify the behavior of BSOUT. When this rou-
taken, the accumulator should hold the number of the logical tine is called, the value to be output should be in the
file to be closed. accumulator.
798-799 $031E-$O3IF ICHKIN 808-809 $0328-^0329 ISTOP
Indirect vector to Kernal CHKIN routine Indirect vector to Kernal STOP routine
This vector is the normal link between the Kernal jump table This vector is the normal link between the Kernal jump table
entry at 65478/$FFC6 and the CHKIN routine at 61702/ entry at 655O5/$FFE1 and the STOP routine at 63086/$F66E.
$F106. You can redirect this vector to a routine of your own if You can redirect this vector to a routine of your own if you
you wish to modify the behavior of CHKIN. When the jump is wish to modify the behavior of STOP. The routines which call
taken, the X register should hold the number of the logical file STOP expect it to return with the status register Z bit set if the
selected as the input source. RUN/STOP key was pressed, or clear otherwise.
However you can redirect this vector to a routine of your own 818-819 $0332-$0333 ISAVE
if you wish to add commands to the machine language moni- Indirect vector in Kernal SAVE routine
tor. The following example adds two new monitor com- This indirect vector appears in the Kernal SAVE routine
mands—P, which behaves like D (disassemble) but routes [$F53E] at the point after the ending address has been stored
output to the printer, and Q, which closes the file to the in 174-175/$AE-$AF and the starting address has been stored
printer: in 193-194/$C1-$C2. The vector normally holds 62798/
0D00 LDA #$0B ;Redirect vector to new handling routine $F54E, the address immediately following the indirect jump.
0D02 STA $032E You can redirect this vector to a routine of your own if you
0D05 LDA #$0D wish to modify the behavior of SAVE.
OD07 STA $032F
ODOA RTS
ODOB CMP #$51 ;Is character code for Q? Screen Editor Indirect Vectors
ODOD BNE $OD1A The next five vectors, 820-829/$0334-$033D, are copied from
ODOF LDA #$04 ;If so, close logical file 4 a table at $C065-$C06E in screen editor ROM by the CINT
0D11 JSR $FFC3 routine [$C07B] during the reset sequence. CINT is also part of
0D14 JSR $FFCC ;Restore normal I/O channels (CLRCH) RUN/STOP-RESTORE, but a flag in the routine is normally
0D17 JMP $B08B ;Retum to monitor main loop used to skip the vector initialization step in this case. As a re-
0D1A CMP #$50 ;Is character code for P?
sult, vector addresses aren't usually changed by RUN/STOP-
GD1C BNE $0D3S
0D1E LDA #$04 ;H so, OPEN 4,4,0 RESTORE.
0D2O TAX
0D21 LDY #00 820-821 $0334-$0335 CTLVEC
0D23 JSR $FFBA Indirect vector in screen BSOUT handling
0D26 LDA #$00 The jump through this indirect vector is taken as the first step
0D28 JSR $FFBD in the screen BSOUT subroutine [$C7B6] which processes
0D2B JSR $FFCO character code values less than 32/$20. At the time the jump
0D2E LDA #$04 ;Set logical file 4 for output is taken, the accumulator holds the current character code. The
0D30 JSR $FFC9 vector normally holds 51129/$C7B9, the address immediately
D033 LDA #$44 ;Change monitor command to D
following the indirect jump. You can change this vector to
(disassemble)
0D35 JMP $B006 ;Return to monitor command processing point to a routine of your own if you wish to change the
printing behavior of character codes in the range 0-31/
loop
$00-$lF. All codes in this range perform cursor movements,
816-817 $0330-$0331 ILOAD color changes, or other control functions rather than printing
characters. If you wish to add new control functions, codes 0,
Indirect vector in Kernal LOAD routine 1, 3, 4, 6, 16, 21-23, 25, and 26 are currently unused.
This indirect vector appears in the Kernal LOAD routine
[$F265] at the point after the starting address (in X and Y 822-823 $0336-$0337 SHFVEC
when the routine is entered) has been stored in 195-196/
$C3-$C4. The accumulator should still contain a value indicat- Indirect vector in screen BSOUT handling
ing whether the operation is a load or a verify (0/$00 for load, The jump through this indirect vector is taken as the first step
nonzero for verify). The vector normally holds 62060/$F26C, in the screen BSOUT subroutine [$C802] which processes
the address immediately following the indirect jump. You can character code values greater than 127/$7F. At the time the
redirect this vector to a routine of your own if you wish to jump is taken, the accumulator holds the current character
modify the behavior of LOAD. code. The vector normally holds 51205/$C805, the address
98 99
824-825 $0338-$0339 $033C-$O33D 828-829
immediately following the indirect jump. You can change this 826-827 $033A-$033B KEYVEC
vector to point to a routine of your own if you wish to change Indirect vector in keyboard scanning routine
the printing behavior of character codes in the range The jump through this indirect vector is taken during the
128-255/$80-$FF. Codes 128-159/$81-$9F perform cursor SCNKEY routine [$C55D] at the point following completion of
movements, color changes, or other control functions rather the keyscan and the evaluation of the shift key status. At the
than printing characters. If you wish to add new control func- point the jump is taken, the accumulator (along with location
tions, codes 128, 131, and 132 are currently unused. 212/$D4) will contain the current keyboard matrix code, and
location 211/$D3 will reflect the current shift key status. The
824-825 $0338-$0339 ESCVEC vector normally holds the address 5O657/$C5E1, the point in
Indirect vector in ESC sequence handling routine the keyscan routine immediately following the indirect jump,
The jump through this indirect vector is taken as the first step but you can redirect the vector if you wish to change the be-
in the screen BSOUT subroutine [$C9BE] which processes ESC havior of the keyscan routine.
(escape) key sequences. At the time the jump is taken, a test
will have determined that the previous character was ESC 828-829 $033C-$033D KEYCHK
(code 27/$lB). The accumulator holds the current character Indirect vector in keyboard scanning routine
code, the one which followed ESC. The vector normally holds The jump through this indirect vector is taken during the
51649/$C9C1, the address immediately following the indirect SCNKEY routine [$C55D] after the character code for the
jump. You can redirect this vector to add your own ESC se- keypress has been read from the decoding table and immedi-
quences. The following example adds ESC T, which moves the ately before the test for a programmable key. At the point the
position of the bitmap/text division of a screen line up one jump is taken, the accumulator will contain the character code
row each time the sequence is used: corresponding to the current keypress and the X register will
1400 LDA #$0B ;Redlrect vector to handling routine contain the current shift key status (from 211/$D3). The vec-
1402 STA $0338 tor normally holds 50861/$C6AD, the point in the keyscan
1405 LDA #$14 routine immediately following the indirect jump, but you can
1407 STA $0339 redirect this pointer to modify the behavior of the keyscan.
140A RTS One use of this vector is to disable programmable keys.
140B CMP #$5E ;Is character t? While the definition strings are handy, sometimes—particu-
140D BEQ $1412 larly when you are adapting programs from the Commodore
140F JMP $C9C1 ;If not, jump to normal processing 64—you might like for them to instead generate their standard
routine
1412 LDA $D8 ;Is a split screen in use? character codes. One way to achieve this is to change this
1414 AND #$40 pointer so that the test for programmable keys is bypassed:
1416 BEQ $140F ;If not, use normal processing routine POKE 828,183
1418 LDA $0A34 ;Is the split already at the top row of the
screen? This changes the low byte of the pointer so that the target ad-
141B CMP #$3A dress becomes 50871/$C6B7, the point in the routine immedi-
141D BCC $140F ;If so, ignore this sequence ately beyond the test for programmable keys.
141F SBC #$08 ;Move the split position up one row (8
scan lines)
1421 STA $0A34 Screen Editor Tables
1424 RTS Locations 830-865/$033E-$0361 are the domain of the screen
editor.
100 101
830-841 $033E-$0349 $034A-$0353 842-851
830-841 $033E-$0349 DECODE the CAPS LOCK decoding table used the wrong value for the
Keyboard table pointers Q key entry. The following shows how to fix the CAPS-Q bug
These six 2-byte pointers hold the starting addresses of the 89- by setting up a new copy of the decoding table for that shift
byte tables used to translate the matrix code for the current pattern:
keypress into a character code: 100 REM ** COPY CAPS LOCK TABLE TO RAM
Pointer Shift pattern Default table address 110 FOR 1 = 0 TO 88:POKE 6912 + I,PEEK(64484 + I):NEXT
830-831/$033E-$033F Unshifted 64128/$FA80 120 REM ** CHANGE INCORRECT CHARACTER CODE FOR Q
832-833/$0340-$0341 SHIFT 64217/$FAD9 130 POKE 6912 + 62,209
834-835/$0342-$0343 Commodore 64306/SFB32 140 REM ** REDIRECT POINTER TO NEW TABLE
836-837/$0344-$0345 CONTROL 64395/$FB8B 150 POKE 840,0:POKE 841,27
838-839/$0346-$0347 ALT 64128/$FA80 (same as A custom table should consist of 89 values in matrix code
unshifted) order. Refer to Tables 9-1-9-5 for a listing of the default ta-
840-841/$0348-$0349 CAPS LOCK 64484/$FBE4 bles. The final value in the table should be 255/$FF, and you
The status of the five shift keys, recorded in 211/$D3, is used should be sure to include the shift key codes in the proper lo-
to select one of the table addresses from this area. If no shift cations. The following program sets up a Dvorak-style
key is pressed, the unshifted table is used. If one shift key is keyboard:
pressed, the appropriate decoding table is selected. If more
than one shift key is pressed simultaneously, the table is se- 100 FOR 1=0 TO 88:READ K:POKE 691.2 + 1 ,K:NEXT
lected as follows: CONTROL has the highest priority; when it 110 POKE 830,0:POKE S31,27:END
is pressed in combination with any other shift keys, the CON- 120 DATA 2 0 , 1 3 , 2 9 , 1 3 6 , 1 3 3 , 1 3 4 , 1 3 5 , 1 7 , 5 1 , 4 4
130 DATA 6 5 , 5 2 , 5 9 , 7 9 , 4 6 , I , 5 3 , 8 0 , 6 9 , 5 4
TROL table is used. The SHIFT and Commodore keys are next 140 DATA 7 4 , 8 5 , 8 9 , 8 1 , 5 5 , 7 0 , 7 3 , 5 6 , 8 8 , 6 8
in priority; however, when they are pressed simultaneously, 150 DATA 7 1 , 7 5 , 5 7 , 6 7 , 7 2 , 4 8 , 7 7 , 8 4 , 8 2 , 6 6
no decoding table is selected (although the combination may 160 DATA 4 3 , 7 6 , 7 8 , 4 5 , 8 6 , 8 3 , 4 7 , 8 7 , 9 2 , 4 2
cause character set switching). ALT and CAPS LOCK have the 170 DATA 5 9 , 1 9 , 1 , 6 1 , 9 4 , 9 0 , 4 9 , 9 5 , 4 , 5 0
lowest priority. They are effective in selecting the decoding ta- 180 DATA 3 2 , 2, 3 9 , 3, 1 3 2 , 5 6 , 5 3 , 9, 5 0 , 52
190 DATA 5 5 , 4 9 , 2 7 , 4 3 , 4 5 , 1 0 , 1 3 , 5 4 , 5 7 , 5 1
ble only if no other shift keys are being pressed. If pressed 200 DATA 8 , 4 8 , 4 6 , 1 4 5 , 1 7 , 1 5 7 , 2 9 , 2 5 5 , 255
simultaneously, both are ignored and the unshifted table is
used. Once a table is selected, its address is loaded into
204-205/$CC-$CD, and the current matrix code in 212/$D4 842-851 $034A-$0353 KEYBUF
is used as an offset to the specific character code to be re- Keyboard buffer
trieved from the table. This ten-byte area is the keyboard buffer. When the SCNKEY
The default decoding table addresses are copied here from routine [$C55D] detects a valid keypress, it generates a cor-
a table at 49263/$C06F in screen editor ROM by the CINT responding character code. The character code is then stored
screen editor initialization routine [$C07B] during the reset se- in this buffer to await processing. (The Kernal GETIN and BA-
quence. CINT is also part of the RUN/STOP-RESTORE se- SIN routines are normally used to retrieve characters from this
quence, but it includes a flag that normally prevents the buffer.) Location 208/$D0 holds the number of characters cur-
vectors from being reinitialized in that case. To redefine the rently waiting in the buffer. The maximum number of charac-
128 keyboard, you need only set up a new decoding table in ters that can be held in the buffer is determined by the value
RAM and change one of the address values here to point to in location 2592/$0A20. If the value there is greater than 10,
the new table. For example, if you've used the CAPS LOCK the keyboard buffer will overwrite the following memory
key, you've probably discovered that it doesn't appear to af- areas such as the tab stop bitmap. When the value in 208/$DO
fect the Q key. Actually, the problem is that whoever prepared equals the value in 2592/$0A20, the buffer is full; any further
102 103
842-851 $034A-$0353 $035E-$0361 862-865
keypresses will be ignored until one or more characters are re- 852-861 $0354-$035D TABMAP
moved from the buffer. Tab stop bitmap
This key buffering system allows for a powerful program- These ten bytes provide an 80-bit map of the display's hori-
ming technique known as the dynamic keyboard. By storing zontal character positions. Each horizontal position in the cur-
character code values in the buffer and storing the number of rently active display has a corresponding bit in the map. For
characters in 208/$D0, a program can appear to type on the the VIC chip's 40-column display, only the first five bytes (40
keyboard. For example, the following lines add a default an- bits) are used. When a bit is set to % 1 , a tab stop is estab-
swer to the INPUT prompt: lished at the corresponding screen column. Printing the TAB
200 POKE 842,89: POKE 208,1: REM PLACE Y IN BUFFER character, code 9/$09, or pressing the TAB key will move the
210 INPUT'ARE YOU SURE";A$ cursor rightward to the next tab stop (or the right window
margin if no tab stops are set between the current cursor posi-
When the INPUT statement begins to look for characters, it tion and the right margin).
will find the Y already in the buffer.
An even more powerful use of the dynamic keyboard During the CINT screen editor initialization sequence, all
technique is to allow a program to execute a series of com- locations in the map are set to 128/$80, which establishes a
mands after it ends. When a program is finished executing, tab stop every eighth column. Printing character code 24/$18
BASIC looks to the keyboard buffer for the characters of the (or pressing SHIFT-TAB) toggles the map bit corresponding to
next command. Thus, any characters placed in the buffer the current cursor column, setting a tab stop if the bit was pre-
while a program is running will effectively be typed if the pro- viously %0 or clearing the tab stop if the bit was previously
gram ends. Since the buffer can hold only ten characters, the % 1 . The ESC Z sequence can be used to clear all tab stops (all
common practice is to print commands at carefully planned locations in the map will be filled with 0/$00), and the ESC Y
places on the screen, then fill the buffer with cursor move- sequence can be used to restore default tab stops (all locations
ment and RETURN characters to execute the commands. The in the map will be filled with 128/S80).
following program illustrates this technique. It creates DATA When the active display is switched, screen editor SWAP-
statements for one of the sprite patterns. You can adapt the PER routine [$CD2E] exchanges the contents of this area with
program for your own needs by changing the values in line the contents of locations 2656-2665/$0A60-$0A69, the stor-
10. AD is the starting address of the data, NI is the number of age area for the inactive display tab stop bitmap. Thus, tab
DATA items to be generated, and LN is the line number of stop settings are preserved while the screen is inactive,
the first DATA statement to be generated. The program prints
a DATA line and a GOTO statement on the screen, then 862-865 $035E-$0361 LNKMAP
places {HOME} {RETURN} {RETURN} in the buffer and ends. Line link bitmap
The buffered characters are executed, entering the DATA line These four bytes are used to provide a 25-bit map of the 25
and restarting the program. rows of the active screen display (bits 0-6 of location
865/$361 are unused). Each row of the currently active dis-
10 AD=3584:NI=64:LN=100!l=0 play has a corresponding bit in the map. When a bit is set to
20 IF I=>NI THEN END % 1 , the corresponding row is linked to the row above as part
30 PRINT"[CLR}";LN;"DATA";:LN=LN+I0:J=0 of a logical line. Bits set to %0 indicate unlinked lines (or rows
40 PRINT P E E K ( A D + I ) ; : I = I + 1 : I P I=>NI THEN 60 that are the first physical line of a logical line). These locations
50 J = J + 1 ; I F J < 8 THEN PRINT"{LEFT},";:GOTO 40
60 PRINT:PRINT"GOTO 20"
are cleared to 0/$00, unlinking all lines, whenever the output
70 POKE 842,I9:POKE 843,13:POKE 844,.13:POKE 2 0 3 , 3 : E window is cleared or reset to full screen size, or whenever the
ND screen editor WINDOW routine is used to change the size of
the output window. A screen line is normally linked to the
one above when the cursor moves onto the line by wrapping
104
A. 105
866-875 S0362-S036B $0380-$039E 896-926
from the right margin of the line above. Line linking can be output, the device number for the selected file will be read
disabled by setting the flag bit in location 248/$F8. from this table. When a file is closed, the Kernal CLOSE rou-
When the active display is switched, the screen editor tine [$F188] removes the file's entry from this table.
SWAPPER routine [$CD2E] exchanges the contents of this
area with the contents of locations 2666-2669/$0A6A-$0A6D, 886-895 $0376-$037F SATBL
the storage area for the inactive display line link bitmap. Thus, Secondary address table for currently open files
the line link status is preserved when the screen is inactive. When a logical file is opened, the OPEN routine [$EFBD] will
OR the specified secondary address for the file with the value
Kernal File Tables 96/$60, then store the result in the next available entry in this
The following three ten-byte tables hold information on any table. When the Kernal CHKIN [$F106] or CKOUT [$F14C]
currently open logical files. The three tables are parallel; the routines are used to select a logical file for input or output, the
entry for a particular file will appear at the same position in secondary address for the selected file will be read from this
all three tables. Location 152/$98 serves as an index to the table. When a file is closed, the Kernal CLOSE routine [$F188]
next available entry in the tables. The fact that there are only removes the file's entry from this table.
ten bytes per table means that no more than ten logical files The Kernal includes a routine [LKUPSA, $F786] to search
may be opened simultaneously. for a particular secondary address in this table.
106 107
927-938 $039F-$03AA $03D2-$03D4 978-980
significant in BASIC program lines). If the character is one of 951-959 $03B7-$03BF INDIN1_RAM1
the numbers 0-9, the carry bit will be clear (carry will be set if
the character is not a digit). If the character was a colon (:), Alternate routine to retrieve a character from variable storage
BASIC'S end-of-statement marker, or a zero byte, BASIC'S This routine retrieves a character from the variable storage
end-of-line marker, the status register Z bit will be set; other- area (bank 1) using locations 36-37/$24-$25 as a pointer and
wise, the Z bit will be clear. the contents of the Y register as an offset from the address in
the pointer. The character will be in the accumulator upon re-
This routine has an alternate entry point at 902/$386, turn from the routine and the system will be left in the alter-
called CHRGOT, which retrieves and tests the current charac- nate bank 14 configuration that includes block 1 RAM.
ter, the one at the address currently in 61-62/$3D-$3E, with-
out updating the pointer.
Since this routine is in RAM, it can be modified to change
960-968 $03C0-$03C8 INDIN2
the way BASIC program text is read. Refer to Chapter 5 for Alternate routine to retrieve a character from program text
details on how you can use this technique to add new com- This routine retrieves a character from program text (bank 0)
mands to BASIC. using locations 38-39/$26-$27 as a pointer and the contents
of the Y register as an offset from the address in the pointer.
927-938 $039F-$03AA INDSUB_RAMO The character will be in the accumulator upon return from the
Alternate routine for reading characters from program text routine and the system will be left in the bank 14
This routine retrieves a character from program text (bank 0). configuration.
The value in the accumulator upon entry specifies the address
of the zero-page pointer containing the base address, and the 969-977 $03C9-$03Dl INDTXT
value in the Y register specifies the offset from this base ad- Alternate routine to retrieve current program text character
dress to the character to be read. The character will be in the This routine retrieves the current program text character using
accumulator upon return from the routine and the system will 61-62/$3D-$3E as a pointer. The character will be in the ac-
be left in the bank 14 configuration. BASIC ROM includes a cumulator upon return from the routine and the system will
collection of character retrieval subroutines (17102-17159/ be left in the bank 14 configuration. The routine is similar to
$42CE-$4307) that make use of this routine. the CHRGOT entry into GHRGET, but without the tests for
character type.
939-950 $03AB-$03B6 INDSUB_RAM1
Alternate routine for reading characters from variable storage 978-980 $03D2-$03D4 ZERO
This routine retrieves a character from the variable storage Null descriptor
area (bank 1). The value in the accumulator upon entry speci- If the routine [$7AAF] which searches for a variable name in
fies the address of the zero-page pointer containing the base the variable table fails to find the name when called by EVAL
address, and the value in the Y register specifies the offset [$7978] or POINTER [$82FA], the address of this area is re-
from this base address to the character to be read. The charac- turned as the variable descriptor address. This prevents vari-
ter will be in the accumulator upon return from the routine able table entries from being created if a variable name is first
and the system will be left in the alternate bank 14 configura- used in an expression argument or in the POINTER function.
tion that includes block 1 RAM. BASIC ROM includes a col- For example, if you use B$ = A$ or AD = POINTER(A$) when
lection of character retrieval subroutines (17102-17159/ no variable A$ exists, no entry for A$ will be created. These
$42CE-$4307) that make use of this routine. three locations are all filled with the value 0/$00, copied here
from ROM along with the preceding subroutines.
108 109
981 S03D5
S03E2 994
110
111
995 S03E3 $03FD-$03FF 1021-1023
the BASIC cold-start sequence to the default foreground and 1008-1020 $03F0-$03FC DMA
background colors, so this location will initially hold 219/$DB, DMA_CALL execution routine
for a light green foreground and dark gray background. The This area holds the RAM-resident portion of the Kernal
value here is not affected by RUN/STOP-RESTORE. DMA_CALL routine [$F7A5]. The routine is copied here from
Kernal ROM during the reset sequence. It is designed to initi-
995 $03E3 FG-JMC1 ate a DMA (direct memory access) command to the REC
Multicolor bitmap color fill value (RAM expansion controller) chip in an installed memory ex-
This location holds the color memory fill pattern for multicolor pansion module. The routine loads the current memory con-
bitmapped mode. When the SCNCLR routine [$6A79] is used figuration register contents, then stores the contents of the Y
to clear the multicolor bitmapped (GRAPHIC 3 or GRAPHIC register in the REC command register address (57089/$DF01)
4) display, all locations in the video matrix area will be filled and stores the contents of the accumulator in the MMU mem-
with the value here. (The SCNCLR routine is also used when ory configuration register (65280/$FF00). If the REC is config-
the clear parameter is specified in a GRAPHIC statement.) In ured in its default state, storing the value in the MMU register
multicolor bitmapped mode, the video matrix area holds color should trigger the specified REC operation. See Chapter 8 for
information for pixels with %01 and %10 bit patterns, so the more information about the REC chip. Upon completion of the
value here determines the default colors for those pixel pat- operation, the original memory configuration register setting
terns in all screen positions after the screen is cleared. will be restored.
For the BASIC graphics routines that draw on the multi-
color bitmapped display, the value in this location will deter- 1021-1023 $03FD-$03FF Unused
mine the color of any lines drawn using color sources 1 or 2. The locations in this range are not used by any system ROM
If color source 1 was specified for the line, the value in the routine, and are thus available for your own programming.
upper four bits here will be stored in the upper four bits of the
video matrix locations corresponding to the line's location in
the bitmap. If color source 2 was specified, the value in the
lower four bits here will be stored in the lower four bits of the
video matrix locations corresponding to the line's location in
the bitmap.
The value in these locations can be changed with the
COLOR statement [$69E2]. The high four bits here are set to
the value in the lower four bits of the foreground color in lo-
cation 134/$86. The lower four bits here are set to the multi-
color 1 value in the lower four bits of location 132/$84. The
location is initialized during the BASIC cold-start sequence to
the default multicolor pixel colors for %01 and %10 patterns,
so this location will initially hold 2O9/$D1, for light green
%01 pixels and white %1O pixels. The value here is not af-
fected by RUN/STOP-RESTORE.
112 113
Bank 0 Working
Storage
VIC Default Screen Memory
1024-2047/$0400-$07FF
This IK area is the default location for the VIC chip's screen
memory in character (GRAPHIC 0) mode. It's not used by
the system for any other purpose. Screen memory can be relo-
cated to any other IK block in RAM by changing the appro-
priate bits in the registers at 53272/$D018 and 56576/$DD00.
For example, screen memory for the system bitmapped modes
(GRAPHIC 1 or GRAPHIC 3) is located at 7168-7423/
$1COO-$1CFR However, the screen editor CINT routine
[$C07B] and Kernal IOINIT routine [$E109], both included in
the reset and RUN/STOP-RESTORE sequences, will reset the
registers to have screen memory at this default area. Conve-
niently, this is the same area used for default screen memory
in the Commodore 64.
When used for screen memory, the first 1000 locations of
this area (1024-2023/$0400-$07E7) correspond to the 1000
character positions of the VIC chip's 40-column X 25-row
screen display. The value in each screen memory location de-
termines what will be displayed in the corresponding position
on the screen. The screen memory values, called screen codes,
are used as indexes into character pattern memory. Any char-
acter pattern can be displayed at any screen location by stor-
ing the appropriate screen code in the appropriate screen
memory location. Appendix C lists the standard character pat-
tern for each screen code. Clearing the screen fills these 1000
memory locations with 32/$20, the screen code for the space
character.
While this area is used as screen memory, the highest
eight locations (addresses 2040-2047/$07F8-$07FF) are used
to hold definition pointers for the eight sprites supported by
the VIC chip. The pattern definition for a sprite requires 64
bytes, so there is room within a 16K VIC video bank for 16384
/ 64, or 256 sprite definitions. These pointer locations each
117
1024-2047 $0400-$07FF $0800-$09FF 2048-25S9
hold a value between 0-255/$00-$FF indicating which 64- GRAPHIC 4) it is possible for the same sprite to have different
byte area within the current video bank will be used to hold shapes in the text and bitmapped portions of the display. The
the pattern definition for the corresponding sprites. Changing SCNCLR routine (also called when you add an extra ,1 to the
the shape of a sprite is as simple as changing the correspond- GRAPHIC statement) copies the text screen sprite pointer val-
ing sprite pointer to select a new pattern definition. To find ues from locations 2040-2047/$07F8-$07FF to the bitmapped
the address specified by the pointer value, multiply the value screen sprite pointers at 8184-8191/$1FF8-$1FFF, but there's
by 64/$40 and add the base address for the video bank. The no ROM routine to perform a copy in the opposite direction—
default pointer values, established by the BASIC cold start ini- from bitmapped screen sprite pointers to text screen sprite
tialization subroutine [$4045], are as follows: pointers—so your text screen pointers should be preserved
Location Sprite Default pointer value even if you change the pointers for sprites displayed on the
2040/S07F8 0 56/$38 bitmapped screen.
2041/$07F9 1 57/$39 The remaining 16 locations in this area, addresses
2042/$07FA 2 58/$3A 2024-2039/$07E8-$07F7, are unused by any system routine.
2043/$07FB 3 59/$3B They are not affected by clearing the screen or changing sprite
2044/S07FC 4 60/$3C pointers, or by reset or RUN/STOP-RE STORE. Thus, they are
2045/S07FD 5 61/$3D available for your own programming uses.
2046/$07FE 6 62/$3E
2047/$07FF 7 63/$3F
The default values point to the eight sprite definition BASIC Runtime Stack
areas at 3584-4095/$0E00-$OFFF. While BASIC initializes 2048-2559/$0800-$09FF
each pointer to a different definition area, this is not manda-
tory. For example, if you want all eight sprites to have the This 512-byte area is used by BASIC for its runtime stack.
same shape you can just design one sprite pattern and store When you use the machine language JSR instruction to call a
the pointer to that pattern in all eight locations. BASIC doesn't subroutine, there must be some way to record the address to
have any statement specifically for changing pointers, so you'll return to upon completion of the subroutine. As explained in
have to use POKE to change the values here. Because the de- the entry for locations 256-511/$D1OO-$O1FF, the return ad-
fault definition area only has room for eight sprites, you'll dress is placed in a special area of memory called the proces-
have to use some other area of free memory if you want to sor stack. BASIC'S GOSUB statement and looping statements
use more than eight sprite shapes. All sprite pattern defini- like FOR and DO also need some place to store the address to
tions must lie within the current 16K video bank. For the de- return to upon completion of the subroutine or loop. In earlier
fault video bank (0-16383/$0000-$3FFF in block 0 RAM), the versions of Commodore BASIC, this information was also kept
free space at 4864-7167/$1300-$lBFF can be used. in the processor stack. However, only 256 bytes of storage
Remember that the sprite pointers are dependent on the space are available in the processor stack, and BASIC allows
current screen memory block, and aren't an absolute feature of only a portion of that to be used while it is in control. This
these locations. The sprite pointers always appear at an offset limits the level to which loops and subroutines can be nested.
of 1016-1023/$03F8-$03FF bytes beyond the specified starting For example, each FOR-NEXT loop requires 18 bytes of stack
address of screen memory. For example, when one of the bit- space, so the Commodore 64's BASIC 2.0 allows loops to be
mapped modes is selected, screen memory (in that case used for nested only nine levels deep. Because the more complex mem-
color information and usually referred to as the video matrix) ory banking routines in the 128 require more machine lan-
moves to 7168-8191/$1COO-$1FFF, so the sprite pointers for guage subroutine calls, the 128's BASIC 7.0 would allow even
the default bitmapped screen are instead located at 8184-8191/ fewer levels of nesting if it used this same system. However,
$1FF8-$1FFR Thus, in split-screen displays (GRAPHIC 2 or BASIC 7.0 instead stores the information for GOSUB, FOR,
and DO in this totally separate runtime stack area.
118 119
2560-2687 $0A00-$0A7F $OA03 2563
Because this storage area does not have to be shared with change the value here to 16387/$4003—the address of the
processor return addresses, as is the case with the processor BASIC warm start routine.
stack, the entire 512-byte space is available. Thus, you can The RUN/STOP-RESTORE sequence in the NMI han-
have up to 28 nested FOR-NEXT loops (each requires an 18- dling routine [$FA40] ends with a JMP ($0A00). Because of the
byte entry on the stack), or up to 102 nested DO loops or cold start's routine initialization, this will normally cause a
GOSUB subroutines (each of which requires a 5-byte entry), or warm start of BASIC. However, you can make RUN/STOP-
any combination thereof. RESTORE cause a jump to another routine by changing the
Using this runtime stack requires slightly more software value in these locations to point to the address of the new
overhead than using the processor stack. The 8502 processor routine. The only restriction is that the target routine must be
has an internal stack pointer register that indicates the position visible in the bank 15 configuration, since that is how memory
of the next available position in the processor stack, and it also is arranged when the JMP is executed.
has PHA and PLA instructions specifically for adding and re- The monitor X command routine [$B0E3] also performs a
moving instructions from this stack. None of this is handled JMP ($0A00), so the value in these locations determines the
automatically for the BASIC runtime stack; instead, the routines address of the routine which will be executed when you use
which use the stack must explicitly update locations 125-126/ that command to exit the built-in machine language monitor.
$7D-$7E, the runtime stack pointer. The GOSUB [$59CF],
FOR [$5DF9], and DO [$5FE0] statement routines add entries 2562 $0A02 DEJAVU
to the stack, and the RETURN [$5262], NEXT [$57F4], and Memory initialization status flag
LOOP [$608A] statement routines can remove entries from the This location is used to indicate whether the RAMTAS routine
stack. The COLLISION statement [$7164] also causes the has been performed. If the RESET routine [$E000] detects that
equivalent of a GOSUB entry to be placed on the stack when the RUN/STOP key is being held down, indicating that the
a collision of the specified type occurs. reset sequence should end by entering the monitor rather than
This area is not used by the system for any purpose other BASIC, then the value here will be tested. If this location con-
than the BASIC stack, so this entire area is available for use by tains the value 165/$A5, the RAMTAS routine will be omitted
machine language programs that don't require BASIC. from this reset sequence. The routine will hold a random
value when the computer is first turned on, but the first call of
the RAMTAS routine [$E093] will initialize this location to
165/$A5. Thus, once RAMTAS has been performed at least
Kernal and Screen Editor Working once, the test of this flag location can be used to prevent its
being performed again when entering the monitor after a re-
Storage set. This allows you to preserve the contents of zero page,
2560-2687/$0A00-$0A7F normally cleared by RAMTAS during the reset.
2560-2561 $OA00-$0AOl SYSTEM-VECTOR $0A03 PALNTS
BASIC restart vector
2563
PAL/NTSC flag
This pair of locations contains the address of the routine that
The IOINIT routine [SE109], part of the RESET sequence,
will be used to restart BASIC. The RAMTAS routine [$E093],
checks the number of scan lines produced by the VIC chip to
part of the reset sequence, puts the value 163 84/$4 000 here— determine whether the 128 is using a NTSC (North American)
the address of the BASIC cold start routine. Unless the Com- or PAL (European/British) video system. This location is set to
modore or RUN/STOP keys are held down, the RESET rou- reflect the result of that test: to 0/$00 for NTSC systems or
tine [$EO0O] ends with a JMP ($0A00) to cold start BASIC. 255/$FF for PAL systems. Later routines that initialize the
One of the final steps in the BASIC cold start routine is to
120 121
2564 S0AO4 S0A09-S0A0A 2569-2570
video chips and timers can then adjust the default settings ac- patterns are normally initialized only during the reset se-
cordingly. This eliminates the need for different versions of quence, which resets this bit to %0 before calling IOINT. Cus-
the Kernal ROM for different countries. tom 80-column characters are usually preserved during RUN/
STOP-RESTORE, which does not affect this bit.
2564 $0A04 INIT_STATUS
System initialization status flag 2565-2566 SO A05-S0A06 MEMSTR
This location is initialized to 0/$00 near the beginning of the Kernal MEMBOT pointer
Kernal RESET routine [$EOOOj. Bits are then set to %1 by later This pair of locations holds the default value of the lowest
routines to indicate that certain initialization steps have been memory address available in block 0 RAM. The value here can
performed. be read or changed using the Kernal MEMBOT routine
Bit 0: This bit is set to %1 during the BASIC cold start routine [$F772], which has a Kernal jump table entry at 65436/$FF9C.
[$4023] to indicate that the cold start has been performed. The The RAMTAS routine, part of the RESET sequence, calls
IRQ handling routine [$FA65] checks this bit and calls the MEMBOT to initialize these locations to 7168/$1COO. How-
BASIC IRQ routine [$A84D] only if the bit is % 1 . The BASIC ever, the value here is not used by any other system routine,
IRQ routine, which handles sprite movement sprite collision so changing this value will not affect system operation in any
detection, and sound generation, copies the contents of a num- way. This is a change from the Commodore 64, where the
ber of shadow locations into VIC and SID hardware registers. value in the MEMSTR pointer is used to establish the lowest
One way to turn off this interrupt routine and gain direct ac- address available of BASIC. In the 128, the start-of-BASIC
cess to the hardware registers is to set this bit to %0. pointer is always initialized to 7169/$1CO1, regardless of the
value here.
Bits 1-5: Unused.
Bit 6: This bit is tested during the screen editor initialization 2567-2568 $0AO7-$0A08 MEMSIZ
(CINT) routine [$C07B] to determine whether the keyboard ta- Kernal MEMTOP pointer
ble pointers and function key definitions need to be initialized. This pair of locations holds the default value of the highest
If the bit is %0, the default pointer values and key definitions memory address available in block 0 RAM. The value here can
will be copied from ROM into the proper areas of RAM; then be read or changed using the Kernal MEMTOP routine
this bit will be set to % 1 . While this bit is % 1 , the pointer and [$F763], which has a Kernal jump table entry at 65433/$FF99.
function key initialization portion of the routine will be skipped. The RAMTAS routine, part of the RESET sequence, calls
CINT is part of both the reset and RUN/STOP-RESTORE se- MEMTOP to initialize these locations to 65280/$FF00. How-
quences, but the pointers and key definitions are normally ini- ever, the value here is not used by any other system routine,
tialized only during the reset sequence, which resets this bit to so changing this value will not affect the system operation in
%0 before calling CINT. Custom keyboard table pointers and any way. This is a change from the Commodore 64, where the
function key definitions are usually preserved during RUN/ value in the MEMSIZ pointer is used to establish the highest
STOP-RESTORE, which does not affect this bit. address available for BASIC variable storage. In the 128, the
Bit 7: This bit is tested during the IOINIT routine [$E109] to top-of-BASlC pointers are always initialized to 65280/$FF0O/
determine whether the 80-column (VDC) character set needs regardless of the value here.
to be initialized. If the bit is %0, the INIT80 routine [$CE0C]
will be called to copy the standard character patterns from 2569-2570 $OA09-$OAOA IRQTMP
ROM into the VDC chip's private RAM; then this bit will be Temporary storage for IIRQ vector during tape operations
set to % 1 . While this bit is % 1 , the character initialization por- These locations are used for temporary storage of the address
tion of the routine will be skipped. IOINT is part of both the value in the IIRQ vector at 788-789/$0314-$0315 during tape
reset and RUN/STOP-RESTORE sequences, but the character operations. The tape routines stash the current IIRQ address
122 123
2571 SOAOB $0A10 2576
here, then substitute the address of the IRQ service routine to not used by any other 128 routine, and is provided strictly to
handle the tape operation. Upon completion of the operation, maintain Kernal jump table compatibility with previous Com-
the original address stored here will be restored to the IIRQ modore models.
vector.
Location 2570/$0A0A is also used as a flag to indicate
whether or not a tape IRQ routine is active. That location is 2575 $0A0F ENABL
initialized to 0/$00 by the IOINIT routine, part of the RESET RS-232 activity flag
sequence, and will also be reset to that value upon completion This location is used during the RS-232 routines to record the
of the tape operation. Thus, a nonzero value in the flag loca- value in the CIA #2 interrupt control register (56589/$DD0D).
tion indicates that a tape interrupt routine is active. CIA #2 interrupt requests generate the NMI interrupts that
drive RS-232 transmission and reception. While the CIA #2
2571 $0AOB CASTON interrupts for RS-232 are disabled, this location will be set to
CIA #1 control register A log 0/$00. When bits are set in the CIA #2 interrupt control regis-
This location is used to record the status of CIA #1 control ter to enable RS-232 operations, the corresponding bits are
register A (56334/$DC0E) during tape operations. also set in this location. If any of the following bits is set to
% 1 , the corresponding interrupt is enabled:
2572 $0A0C Bit Interrupt source RS-232 activity
CIA #1 interrupt control register log 0 Timer A bits being transmitted
1 Timer B bits being received
This location is used to record the status of the CIA #1 inter- 4 FLAG line waiting for start bit to be received
rupt control register (56333/$DC0D) during tape operations.
This location is initialized to 0/$00 during the IOINIT routine
2573 $0A0D [$E109], part of the reset and RUN/STOP-RE STORE
CIA #1 timer A status log sequences.
The CIA #1 control register A log value from 25 71 /$0AOB is
stored here during certain tape operations to preserve the 2576 $0A10 M51CTR
timer A status. RS-232 control register
This location controls some of the operating characteristics of
2574 $0A0E TIMOUT the RS-232 interface. When a file is opened to device 2, the
IEEE timeout flag first character of the filename is copied here. Although RS-232
When the VIC-20 was introduced, its Kemal included a jump communications in the 128 are managed by software, the bits
table entry (SETTMO, at 65442/$FFA2) to support a proposed of this location are defined to simulate the control register of a
IEEE bus interface. The IEEE bus is the parallel data bus used 6551 UART chip, a hardware device for controlling serial com-
by Commodore's original PET/CBM models for communica- munications. The bits are used as follows:
tions with peripheral devices. The interface was never intro- Bits 0-3: These bits determine the baud rate for both transmis-
duced, but the Kernals of all subsequent Commodore models sion and reception—the rate (in bits per second) at which bits
have slavishly included the SETTMO jump table entry. In the will be sent or received. Valid settings are as follows:
128, the SETTMO routine [$F75F] does nothing more than
store the accumulator contents in this location. This location is
124 125
2577 $OA11 $OA11 2577
Bits Baud rate second character of the filename, if any, is copied here. Al-
Bit though RS-232 communications in the 128 are managed by
3 2 1 0 Value
0 0 0 0 0/$0 user defined software, the bits of this location are defined to simulate the
0 0 0 1 1/*1 50 baud command register of a 6551 UART chip, a hardware device for
0 0 1 0 2/$2 75 baud controlling serial communications. The bits are used as follows:
0 0 1 1 3/$3 110 baud Bit 0: This bit controls the handshaking mode for RS-232
0 1 0 0 4/$4 134. 5 baud transmission and reception. The RS-232 interface consists of
0 1 0 1 5/$5 150 baud
1 1 0 300 baud three primary signal lines—transmitted data, received data,
0 6/$6
and ground—plus a number of supplementary control lines—
0 1 1 1 7/%7 600 baud
1 0 0 0 8/$8 1200 baud data set ready (DSR), data terminal ready (DTR), ready to send
1 0 0 1 9/$9 1800 baud (RTS), and clear to send (CTS). The control lines are called
1 0 1 0 10/$A 2400 baud handshaking lines because they allow the sending and receiv-
When the user-defined rate is selected, the baud rate is deter- ing units to exchange signals (handshakes) indicating whether
mined by the value in locations 2578-2579/$0A12-$0A13. data is being successfully transmitted and received. The 128's
The remaining possible bit patterns, %1011-%llll / result in RS-232 software interface can operate in two different modes:
3-line, where none of the handshaking lines are used, and x-
invalid baud rates. line, where all of the handshaking lines are used. These bits
Bit 4: Unused. control the interface mode as follows:
Bits 5-6: These bits determine the number of data bits in each Bit 0 Interface mode
character sent or received (sometimes referred to as the word 0 3-line interface {no handshaking)
size). The total character length will also include a start bit, 1 x-line interface {full handshaking)
possibly a parity bit, and one or more stop bits. For 3-line mode, the output handshaking lines (DTR and RTS)
Bits Bit Number of will be held at a constant high ( + 5 volts) level. The input
6 5 value data bits handshaking lines {DSR and CTS) will be ignored.
0 0 0/$00 8 data bits
0 1 32/$20 7 data bits Bits 1-3: Unused.
1 0 64/$40 6 data bits Bit 4: For unknown reasons, Commodore literature continues
1 1 96/S60 5 data bits to indicate that this bit controls the duplex mode of the RS-
Bit 7: This bit determines the number of stop bits in each 232 interface. The bit is supposed to select full duplex when
character. Stop bits are %1 bits added to the end of the char- set to %0 or half duplex when set to % 1 . However, this bit is
acter. They represent the minimum amount of time the com- not checked by any RS-232 routine, and its setting has no ef-
munications line will remain at the low (%1 bit) level before fect on the operation of the interface.
the next start bit can be sent or received. Duplex is often confused with local echo. A full-duplex
interface can simultaneously send and receive data, while a
Bit 7 Bit value Number of stop bits half-duplex interface can send data and receive data, but not
0 0/$00 1 stop bit both at the same time. The 128's RS-232 interface always op-
1 128/S80 2 stop bits erates in full-duplex mode. In casual usage, however, duplex is
often used to describe whether or not the system echoes back
2577 $OA11 M51CDR the characters it receives. In remote echo mode {incorrectly re-
RS-232 command register ferred to as full duplex), the system displays only characters
This location controls some of the operating characteristics of received from the remote unit (the one being called). The as-
the RS-232 interface. When a file is opened to device 2, the sumption is that the remote unit will send back an "echo" of
127
126
2577 $OA11 S0A14 2580
each character it receives from the system. In local echo mode bit for each received character will be ignored. When space
(incorrectly called half duplex), the system displays the charac- parity is selected, the transmitted parity bit will always be %0
ters it sends as well as the ones it receives. The assumption in and the received parity bit will be ignored.
this case is that the remote unit will not echo the characters it
receives. 2578-2579 $0A12-$0A13 M51AJB
Bits 5-7: This bit controls the parity generated for transmitted RS-232 baud-rate factor
characters and the parity tested for in received characters. Par- The value in these locations determines the baud-rate timing
ity is a simple method of detecting some errors in data trans- factor. When a file is opened to device 2, the third and fourth
mission. A parity bit can be added between the data and stop characters of the filename are copied here (if the filename has
bits in the character. The value of the parity bit is selected to that many characters). However, the filename characters are
make the total number of %1 bits in the character (not count- meaningful only if a user-defined baud rate has been speci-
ing stop bits) either even or odd. The receiving unit can then fied—if bits 0-3 of the first character of the filename (copied
count the number of %1 bits in the received character to de- into 2576/$0A10) are %0000. In that case, the value in these
termine if bits have been garbled in transmission. Parity locations specifies the baud rate according to the following
checking did not work properly in the original versions of the formula:
Commodore 64 Kernal ROM, but that problem has been cor- baud rate = clock frequency/(2 * (rate factor + 100))
rected in the 128's Kernal (and in the version of 64 Kernal
ROM for the 128's 64 mode). Possible parity selections are as For the standard baud-rate settings, the Kernal RS-232 OPEN
follows: routine copies the proper rate factor into these locations from
tables in Kernal ROM (59472-59491/$E850-$E863 for NTSC
Bits Parity selection systems or 59492-59511/$E864-$E877 for PAL systems). The
7 6 5 two separate tables are required because the different video
x x 0 parity not used
0 0 1 odd parity systems use different clock frequencies.
Oil even parity There's rarely a need to specify a custom baud rate, since
10 1 mark parity the standard settings encompass all standard rates that the 128
1 1 1 space parity can support. (The 128 cannot handle RS-232 communications
If bit 5 is %0, no parity bit will be generated in transmit- faster than 2400 baud, so don't try to specify a faster rate.)
ted characters and the system will expect incoming characters However, should you ever want to do so, the formula for the
to have no parity bit. This selection is common when a word rate factor is as follows:
size of eight data bits per character is used. Odd parity means rate factor = {(clock frequency / desired baud rate)/ 2) — 100
that a parity bit will be generated for each transmitted charac- The clock-frequency value is 1022730 for NTSC (North Amer-
ter such that the character will have an odd total number of ican) systems or 985250 for PAL (European) systems. The low
%1 bits (not counting the stop bits). When even parity is se- byte of the resulting factor should be stored in 2578/$0A12
lected, the parity bit will be set to make the total number of and the high byte in 2579/$0A13.
%1 bits in the character even. For either even or odd parity,
the number of %1 bits in each character received will be 2580 $0A14 RSSTAT
counted and compared against the parity selection. If the num- RS-232 status register
ber does not match the specified parity type, the error will be Although RS-232 communications in the 128 are managed by
indicated by setting bit 0 of the status register location (2580/ software, the bits of this location are defined to simulate the
$0A14) to % 1 . Mark and space parity are alternate forms of no status register of a 6551 UART chip, a hardware device for
parity. When mark parity is selected, the parity bit for each controlling serial communications.
transmitted character will always be set to % 1 , and the parity
128 129
2580 S0A14 $0A16-$0A17 2582-2583
It is possible to read the value here directly, but this loca- low (0 volts) state during either transmission or reception of
tion can also be read using the Kernal READSS routine characters. When x-line handshaking is used, the external de-
[$F744] if the current device number in location 186/$BA is 2 vice connected to the interface is expected to hold the DSR
(for RS-232). The READSS routine also has a Kernal jump ta- line high ( + 5 volts). If the line goes low, it is taken as an indi-
ble entry at 65463/$FFB7. From BASIC, the reserved variable cation that nothing is connected to the interface.
ST will reflect the value in this location as long as the current
device number is 2. This location is initialized to 0/$00 each Bit 7: This bit is the break indicator. A break occurs when,
time the Kernal OPEN routine is called to open a file to device during reception of characters, a byte is received consisting of
2, the RS-232 interface. The value here is also reset to zero all %0 bits not followed by stop bits (which are always %1).
after each call to the READSS routine when device 2 is active, In other words, a break occurs if the received data signal line
including each reference to the ST variable in a BASIC program. is held at the %0 bit ( + 5 volt) level for longer than the time
required to receive a character.
Bit 0: This bit is the parity-error indicator. It is used only
when either even or odd parity is selected, and is relevant S0A15 BITNUM
only to received characters. The bit is set to %1 whenever a
2581
character is received for which the calculated total of %1 bits RS-232 bit count
received for the character does not match the specified parity This location will hold the number of bits prior to the parity
selection. and stop bits for each character received or transmitted. The
location is initialized during the RS-232 OPEN routine [$F040]
Bit 1: This bit is the framing-error indicator. The bit is set to to the number of data bits (specified in bits 5-6 of 2576/
%1 when a framing error occurs—when no stop bits are found $0A10) plus 1. For transmission, the value here is copied into
following the specified number of data and parity bits. location 180/$B4, the countdown of bits to send. For recep-
Bit 2: This bit is the receiver buffer-overflow indicator. It will tion, the value here is copied into location 168/$A8, the
be set to %1 when a character is received after the RS-232 in- countdown of bits remaining to be received.
put buffer at 3072/$0C00 is already full.
2582-2583 $0A16-$0A17 BAUDOF
Bit 3: This bit is the receiver buffer-empty indicator. It will be
RS-232 baud-rate timing constant
set to %1 whenever there are no characters waiting to be read
Commodore's insistence on providing an exact software emu-
from the input buffer. This bit should be tested before each at-
tempt to read characters from the RS-232 interface. lation of the 6551 UART chip leads to some odd software gy-
rations. The baud-rate timing factor specified in locations
Bit 4: This bit is the CTS-missing error indicator. It is used
2578-2579/$0A12-$0A13 must be converted back into an ab-
only when x-line handshaking is selected. The bit will be set
to %1 if the CTS (clear to send) input line drops to a low (0 solute timing value. The Kernal OPEN routine for RS-232 per-
volts) state while data is being transmitted. When x-line forms the following calculation:
handshaking is used, the external device connected to the in- timing constant = (rate factor * 2) — 200
terface is expected to hold the CTS line at a high ( + 5 volts) Given the formula for rate factor, this is equivalent to:
state. If the line goes low, it is taken as an indication that the timing constant = clock frequency / baud rate
external device is not ready to receive data, so transmission is This yields the number of system clock cycles required to send
suspended until CTS goes high. or receive each bit at the specified baud rate. The resulting
Bit 5: Unused. This bit should always be %0 when read. value is stored in these locations. When transmission or recep-
Bit 6: This bit is the DSR-missing error indicator. It is used tion is initiated, the value here is copied into one of the CIA
only when x-line handshaking is selected. The bit will be set #2 timers. This determines the time between the NMI inter-
to %1 if the DSR (data set ready) signal input line drops to a rupts that drive the transmission or reception of bits.
130 131
2584 $0A18 S0A1D-60A1F 2589-2591
2584 S0A18 RIDBE In that case, the buffer is already full, and some characters
Index to first character in RS-232 input buffer must be transmitted before any more can be added to the buffer.
This location holds the offset from the start of the RS-232 in-
put buffer to the position where the next character received 2588 $OA1C SERIAL
will be stored. The input buffer normally begins at location Fast serial mode flag
3072/$0C00. The value here is incremented before each re- This location is used to indicate whether the currently speci-
ceived character is added to the buffer, unless incrementing fied serial bus device, such as the 1571 disk drive, is capable
would make the value here equal to the value in location of fast serial communications. The location is initialized to
2585/$0A19. In that case, a buffer overflow has occurred 0/$00, the value for standard (slow) communications, during
{more characters have been received than the buffer can hold), the IOINIT routine [$E109]. The routines that handle the serial
so bit 2 of the status location (2580/S0A14) is set to % 1 . bus TALK and LISTEN commands attempt a fast serial hand-
shake. If the external device responds properly, bits 6 and 7 of
2585 $0A19 RIDBS this location will be set to % 1 . Bit 7 indicates that the external
Index to last character in RS-232 input buffer device is capable of fast transmission and reception of individ-
This location holds the offset from the start of the RS-232 in- ual bytes. The bit is reset to %0 during the Kernal routines
put buffer to the position of the next character waiting to be that handle the serial bus UNTALK and UNLISTEN routines.
removed from the buffer. The buffer normally begins at 3072/ Bit 6 indicates that the system is capable of high-speed burst
$0C00. The value here is incremented after each character is mode loading.
retrieved from the buffer. When the value here equals the
value in location 2584/$0A18, all characters have been re- 2589-2591 $OA1D-$OA1F TIMER
moved and the buffer is empty. In this case, bit 3 of the status Software jiffy timer
location (2580/$0A14) will be set to % 1 . The three-byte value in these locations is decremented 60
times per second by the Kernal UDTIM routine [$F5F8], part
2586 S0A1A RODBS of the IRQ sequence. Thus, these locations function in a man-
Index to first character in RS-232 output buffer ner opposite that of the jiffy clock at 160-l62/$A0-$A2,
This location holds the offset from the start of the RS-232 out- which is incremented 60 times per second by UDTIM. The or-
put buffer to the position of the next character awaiting trans- der of bytes here is the opposite of the order of bytes in the
mission. The output buffer normally begins at 3328/$0D00. jiffy clock: $OA1D is the low byte and $OA1F is the high byte.
The value here is incremented after each character is removed Since the countdown for this timer is handled automati-
from the buffer for transmission. When the value here equals cally during the IRQ, it is useful for many timing applications.
the value in location 2587/$0AlB, all characters awaiting The way to use this timer is to load the locations with the
transmission have been sent and the buffer is empty. value in jiffies (1/60-second intervals) for the desired delay
period, then test for a value of $FF in location 2591/$OA1F.
2587 $OA1B RODBE That location will contain $FF after the three-byte value rolls
Index to last character in RS-232 output buffer over from $000000 to $FFFFFF at the end of the countdown.
The highest allowable initial value when using this scheme is
This location holds the offset from the start of the RS-232 out-
$FF0000, which corresponds to 16,711,680 jiffies—a little over
put buffer to the position where the next character will be
three days.
added to await transmission. The output buffer normally be-
There is one caution in using this location from BASIC.
gins at 3328/S0D00. The value here is incremented before
The SLEEP statement routine [$6BD7] uses this timer for its
each character is added to the buffer, unless the incrementing
delay countdown, so any use of the SLEEP statement will
would make the value here equal the value in 2586/$0AlA.
overwrite any values you may have stored in these locations.
132 133
2592 $0A20 $0A25 2597
134 135
2598 $0A26 $0A2C 2604
2598 $0A26 BLNON blink rate for the VIC screen is about every 2/3 second. The
Cursor blink flag initialization value is read from ROM, so the 40-column blink
Bit 6 of this location controls whether the cursor on the 40- rate is not programmable.
column (VIC) screen will blink. When the bit is %0, the cursor
blinks at a rate determined by location 26O0/S0A28. When the 2601 $0A29 GDBLN
bit is % 1 , the cursor will be a solid, unblinking block. This lo- Character under cursor
cation is initialized to 0/$00 during the CINT screen editor This location is used to hold the original (unblinked) screen
initialization routine [$C07B], so the default cursor will be code for the character at the current 40-column screen cursor
blinking. The bit can be set to %1 using the ESC E key se- position. If the cursor is moved from the current position with-
quence, and cleared to %0 using ESC F. out printing a new character, this value will be restored to the
Bit 7 of this location indicates the blink phase of the position when the cursor is moved.
cursor on the 40-column (VIC) screen. When the bit is %0, the
character at the cursor position is in its original state. When 2602 $0A2A GDCOL
the bit is % 1 , the character is reversed to provide the cursor Color under cursor
blink effect. This location is used to hold the original color of the character
at the current 40-column screen cursor position. If the cursor is
2599 $0A27 BLNSW moved from the current position without printing a new char-
Cursor enable flag acter, this value will be restored to corresponding color mem-
This location controls whether a cursor will be present on the ory location for the position when the cursor is moved.
40-column (VIC) screen. The cursor will be enabled when the
value here is zero and disabled when this location contains any 2603 $0A2B CURMOD
nonzero value. This location can be used to enable the cursor VDC cursor mode
when it is normally turned off. For example, the following This location is a shadow for VDC internal register 10/SOA.
statement provides a cursor at the prompt (GET and GETKEY See the entry for that register in Chapter 8 for details. The
don't normally provide a cursor): value here is copied into the register every time the screen
300 POKE 2599,0: PRINT"PRESS A KEY: ";: GETKEY K$ editor routines are used to print a character to the 80-column
screen.
2600 $0A28 BLNCT
Cursor blink countdown 2604 $0A2C VM1
This location determines the delay between cursor blinks for VIC text screen and character base
the 40-column (VIC) screen. Bit 6 of location 2598/$0A26 This location is a shadow for the VIC chip screen and character
must be %0 to enable cursor blinking. The value here is base address register (53272/$D018) for the text (GRAPHIC 0)
decremented on each pass through the screen editor IRQ rou- screen, or for the text portion of a split display. The value here
tine. Whenever the value reaches zero, the blink phase of the is copied into the VIC register during the text screen-setup
cursor changes and bit 7 of the screen code at the cursor posi- portion of the screen editor IRQ routine [$C194]. Refer to the
tion is toggled. This reverses the character at thai position. discussion of the register in Chapter 8 for details. During the
The value here is reinitialized to 20/$ 14 whenever it counts screen editor initialization [$C07B], this location is set to
down to zero. It takes two countdowns to complete a cursor 20/$14. That value places screen memory at 1024/$0400 and
blink (one while the character is in its normal state and one character memory at 4096/$1000. If the SHIFT-Commodore
while it is reversed), so 40 passes of the screen editor IRQ rou- combination is detected during the SCNKEY routine [$C55D],
tine are required for each cursor blink. As a result, the cursor- bit 1 of this location is toggled. This switches the character set
base address between 4096/S1000 and 6144/$1800.
136 137
2605 S0A2D $0A34 2612
The default value for this location, set during the screen editor the operation and the register is reset to 0/$00 to disable all
initialization routine [SC07B], is 208/$D0, which places the sprites for the duration of the operation. The VIC chip requires
default split at screen row 20. The value here can be changed extra timing cycles while sprites are active, so they are dis-
in BASIC by specifying a split parameter with the GRAPHIC abled to avoid disrupting the precise timing required for tape
statement. and serial operations. Once the operations are complete, the
value here is restored to the VIC register.
2613 $OA35 FNADRX
Temporary storage for X register 2617 $0A39 BLANKING
This location is used to preserve the contents of the X register Temporary storage for VIC control register
during the Kernal routine that reads a character from a file- This location is used to hold the value in the VIC control reg-
name [$F7AE]. ister at 53265/$D011 during tape operations. The register
value is stored here at the beginning of the tape operation,
2614 $0A36 PALCNT before bit 4 of the register is set to %0 to blank the screen
Jiffy clock compensation flag during the operation. Upon completion of the tape operation,
In systems using the PAL video format, this location is used as the value here is restored to the register.
a counter during the Kernal UDTIM routine [$F5F8], It is in-
cremented each time UDTIM is called to update the jiffy clock 2618 $0A3A HOLD_OFF
locations (160-162/$A0-$A2). When the count has reached 5, Custom mode flag
the UDTIM routine is repeated and the counter is reset to Normally, the system clock is set for the slow (1-MHz) rate
zero. This triggers an extra update of the jiffy clock every fifth and sprites are disabled during tape and disk operations to in-
IRQ in PAL systems, so that ten extra jiffy clock "ticks" occur sure proper timing. However, this location can be used to
for each 50 IRQs. This means that the jiffy clock still incre- allow the VIC clock and sprite registers to retain their current
ments 60 times per second on PAL-video 128s where the IRQ settings during such operations. When bit 7 of this location is
rate is only 50 per second. For systems using the NTSC for- set to % 1 , the registers are left unchanged. This location is ini-
mat, this portion of the UDTIM routine is skipped, so the loca- tialized to 0/$00 by the IOINIT routine [$E109], part of the re-
tion will always hold its initial value of zero. set sequence. That setting is not changed by any ROM routine,
so this feature is not used by the system.
2615 $0A37 SPEED
Temporary storage for clock rate register 2619 $0 A3B LDTB 1_SA
This location is used to hold the value in the VIC system clock Starting page for 40-column screen memory
rate register (53296/SD030) during tape and serial bus opera- The value in this location is used during the screen editor
tions. The current register value is stored here at the beginning routines to determine the starting page for 40-column (VIC)
of the operation and the register is reset for slow (1-MHz) screen memory. During the screen editor initialization routine
mode for the duration of the operation; then the value here is [$C07B], this location is set to the value in location 49228/
restored to the register once the operation is completed. $C04C, which is currently 4/$04. This specifies screen mem-
ory at address 1024/$0400.
2616 $0 A38 SPRITES The value here determines where the screen editor thinks
Temporary storage for sprite enable register VIC screen memory begins, but not the actual starting address
This location is used to hold the value in the VIC sprite enable of the screen. (This location is not a shadow for a VIC regis-
register (53269/$D015) during tape and serial bus operations. ter.) The actual screen starting address is determined by the
The current register value is stored here at the beginning of
140 141
2620-2621 $0A3C-$0A3D $0AA0-$0AA7 2720-2727
decimal) format. The base conversion routine [$BA47] puts the and the routine to test the next buffer character [$B8E7] all
value to be converted into 2720-2723/$0AA0-$0AA3 for stash the X register contents here upon entry, and restore the
manipulation. The routine to print octal, binary, or decimal value to the X register upon exit. The routine to decrement the
values uses 2720-2723/$0AA0-$0AA3 to hold the value to be pointer address or line count stored in 96-98/$60-$62 uses
displayed. this location to hold the amount by which the stored value is
to be decremented.
2720-2729 $0AA0-$0AA9 ASMBUF
Instruction assembly buffer 2736 $0AB0 Unused
The assemble routine [$B406] packs the three-character mne- This location is not used by any 128 ROM routine, and is thus
monic in the instruction being assembled into two bytes and available for your own programming.
stores them in 2720-2721/$0AA0-$0AAl. If characters follow
the mnemonic, they are copied into 2722-2729/$0AA2-$0AA9. 2737 $0ABl OPCODE
If a numeric parameter is found, a dummy value consisting of Calculated opcode
a $ character followed by either two or four zeros (depending The assemble routine [$B406] uses this location to hold the
on whether the value is greater than 255) is substituted. This opcode calculated for the instruction being assembled.
character pattern is then evaluated to determine the addressing
mode for the instruction. 2738 S0AB2 XSAVE
Temporary storage for X register
2730 $0AAA FORMAT The monitor indirect fetch [$B11A], indirect store [$B12A], and
Instruction format flag indirect compare [$B13D] routines stash the value in the X reg-
The routine to calculate the mnemonic and addressing mode ister here upon entry, then restore the value to the X register
for an opcode [$B659] uses this location to hold a flag value upon exit.
indicating the addressing mode in use, which determines the
format in which the instruction must be displayed or entered. 2739 $0AB3 DIRECTION
Transfer direction flag
2731 $0AAB LENGTH The monitor compare/transfer routine [$B231] uses this loca-
Instruction length tion in execution of the T (transfer) command to indicate the
The routine to calculate the mnemonic and addressing mode direction in which bytes are to be transferred. For downward
for an opcode [$B659] uses this location to hold the number of moves (source address greater than destination address), the
bytes which should follow the opcode in the instruction (0-2). flag will be set to zero; for upward moves (destination address
greater than source address), the flag will be set to 128/S80.
2732-2734 $0AAC-$0AAE MSAL
Three-character mnemonic pattern 2740 $0AB4 COUNT
The assemble routine [$B406] stores the first three-character Digit counter
group from the input line in these locations for evaluation as The routine to convert input parameters into numeric values
an ML mnemonic. [$B7CE] uses this location to hold a count of the hexadecimal
digits in the converted value. The routine to print values in oc-
2735 $0AAF SXREG tal, binary, or decimal [$BA47] uses this location as a counter
Temporary storage tor X register of digits printed in the value being displayed.
The subroutine to determine the proper opcode for a mne-
monic [$B57C], the routine to print hexadecimal byte values,
144 145
2741 $0AB5 $0AC6-$0AFF 2758-2815
2741 $0AB5 NUMBER Thus, this location will normally contain 255/$FF upon com-
Temporary storage for parameter conversion pletion of either routine.
The routine to convert input parameters into numeric values
[$B7CE] uses this location to hold the numeric value of the in- 2753-2756 $0ACl-$0AC4 PAT
put digit currently being evaluated. Table of identifiers for function ROMs
The Kernal routine which tests for the presence of function
2742 $0AB6 SHIFT ROMs [$E26B] initializes these locations to 0/$00 before
Number of bits per digit for base checking any of the four possible ROM address slots. A ROM
The routine to convert input parameters into numeric values is considered present in the slot if the character codes for the
letters CBM are found at an offset of seven bytes from the
[$B7CE] and the routine to print values in octal, binary, or starting address of the slot. If this test pattern is found, the
decimal [$BA47] use this location to hold the number of bits to function ROM ID byte is copied from an offset of six bytes be-
be interpreted per digit for the value being converted or yond the starting address of the slot into the corresponding lo-
displayed. cation in this table:
2743-2745 $0AB7-$0AB9 TEMPS Location ROM slot address
Monitor temporary storage 2753/$0ACl 32768/$8000 internal
2754/$0AC2 49152/$C0O0 internal
The routine to convert input parameters into numeric values 2755/$0AC3 32768/S8000 external
[$B7CE] uses these locations as working storage when evaluat- 2756/$0AC4 49152/$C0O0 external
ing decimal digits. Monitor routines which accept two or more
address parameters store the second (ending) address here. For If the identifier byte is l/$01, the cartridge is autostarting
upward transfers, the compare/transfer routine [$B231] moves and the test routine immediately calls the cold-start vector for
the value here to the working pointer at 102-104/$66-$68. that ROM. Otherwise, the Kernal PHOENIX routine [$F867],
part of the BASIC cold-start sequence, will call the cold-start
2746-2751 $OABA-$OABF Unused vector for any ROM slots with nonzero entries in this table.
These locations are not used by any 128 ROM routines, and 2757 $0AC5 DK_FLAG
are thus available for your own programming.
This location is mentioned in Commodore literature as "reserved
for foreign screen editors/' but its exact use is unclear. It is un-
Kernal Working Storage used by any routine in the U.S. version of the system ROMs.
2752-2815/$OAC0-$OAFF 2758-2815 $0AC6-$0AFF Unused
2752 $OACO CURBNK This 58-byte area is described in Commodore literature as "re-
Counter for function ROM testing served for system use." However, no routines in the current
version of the system ROMs make use of any of these loca-
Both the Kernal routine which checks for the presence of ROM tions. Still, unless you are desperate for free locations outside
in the internal and external (cartridge) ROM address slots the BASIC area, it's probably best to avoid using these loca-
[$E26B] and the Kernal PHOENIX routine [$F867] which ini- tions to insure compatibility with future versions of the ROM.
tializes function ROMs use this location as a countdown for
the number of slots remaining to be tested. The location is set
to 3, then decremented each time a slot is checked or initial-
ized. The routines end when the value here rolls over from
0/$00 to 255/$FF after the fourth slot is tested or initialized.
146 147
2816-3071 $0B00-$0BFF $0C00-$OCFF 3072-3327
Cassette Buffer and Disk Boot Buffer track 1 of the disk are read into this area. The first three bytes
of the buffer are then examined. If those locations (the first
2816-3071/$0B00-$0BFF three bytes from the sector) contain the character codes for the
The first 192 bytes of this area (2818-3007/$0B00-$0BBF) are letters CBM, then the routine assumes that a boot disk has
used for the cassette buffer. When you're reading from tape, been found and proceeds with the boot process. Refer to the
file headers are loaded into this area until one is found with entry in Chapter 9 for details. It would be possible to simulate
the specified filename. When you're writing to tape, this area a boot by filling the buffer with the proper values, then jump-
is used to assemble the tape header for the file. When the ing into the BOOT_CALL routine at address 63737/$F8F9.
buffer contains a tape header, the locations are used as follows: The B0OT_CALL routine is normally executed during
Location Function each reset as part of the BASIC cold-start sequence. It can also
2816/$0BO0 Header type identifier be called from the Kernal jump table entry at 65363/$FF53,
2817-2818/$0B01-$0BO2 Starting address for file and can be initiated from BASIC via the BOOT statement.
2819-2820/$OB03-$OB04 Ending address for file Actually, the cassette buffer is not located absolutely at
2821-3007/$OB05-$OBBF Filename this area. The base address of the cassette buffer is determined
A header type identifier of 1 indicates a relocatable program by the value in locations 178-179/$B2-$B3. Those locations
file; 3 indicates a nonrelocatable program file; 4, a data file; are initialized to 2816/$0BO0 during the RAMTAS routine
and 5, an end-of-tape marker. A type identifier value of 2 [$E093], part of the reset sequence. No system ROM routines
means that the block contains data rather than a header. Al- change that setting, but another free 192-byte area could be
though the filename can be up to 187 bytes long, such names used, with two restrictions: the buffer must start at an address
are unusual. When a header is read into the buffer, only the greater than 511/S1FF, and the buffer must be visible in the
first 16 characters of the filename will be displayed following bank 15 memory configuration. The disk-booting routines, on
the FOUND message. When a header is being assembled, all the other hand, do use the absolute address of this area. This
unused filename bytes will be set to 32/$20, the value for the area will always be used as the boot sector buffer, regardless
space character. of the value in the cassette buffer pointer.
The cassette buffer is used to hold blocks of data when If tape data storage is not being used, this 256-byte area is
data files are read from or written to tape. When a data file is available for other uses, such as to hold short machine lan-
being written, after the header is written to tape, the first byte guage routines. The cassette buffer has been a popular area for
here is set to 2, the identifier for a data block; then the re- ML since the days of the first Commodore PET/CBM comput-
maining 191 bytes are filled with the data to be written to the ers. However, the contents of this area will be overwritten
file. Only when the buffer is completely full is the block of whenever the system attempts to boot a disk, including the
data actually added to the file. This is why it is important to time during any reset when the drive is turned on and con-
properly close any file opened for writing. If the file is not tains a disk. You should choose another area if you want your
closed, the last block of data will not be written to tape. When machine language to survive intact following a reset.
a file is opened for reading, after the proper header is identi-
fied, the first block of data is read into the buffer. Subsequent
bytes will be read from the buffer—not directly from tape— RS-232 Input Buffer
until all 191 data bytes have been read from the buffer; then 3072-3327/$0C00-$0CFF
the next block will be read into the buffer. See Chapter 9 for The routines that receive characters via the RS-232 interface
more information on tape data storage. are executed during NMI interrupts. Any characters received
In the 128, this area has a second function: the boot sector are held in this area until they can be read, usually by using
buffer. If the BOOT_CALL routine [$F890] finds a disk in the the Kernal GETIN routine. This is a circular buffer with no
specified drive when it is called, the contents of sector 0 of fixed beginning or end. Location 2585/S0A19 holds the offset
148 149
3328-3583 $ODOO-$ODFF $1000-$10FF 4096-4351
from the starting address of the buffer to the next character changes the address in the pointer, so the buffer will be lo-
waiting to be read (called the head of the buffer). Location cated here unless you explicitly move it. However, the buffer
2584/$0A18 holds the offset to the next free position in the can be moved to another free area of memory simply by
buffer (called the tail of the buffer). The buffer is considered changing the address in the pointer. (The area selected must
empty when the two offset addresses are equal, and full when be visible in the bank 15 configuration.)
the buffer tail offset is one less than the head offset. Bits 2 and If RS-232 communications are not used, this buffer area,
3 of the RS-232 status byte at 2580/$0A14 indicate, respec- along with the one at 3072-3327/$0CO0-$0CFF, is available
tively, when the buffer is full or empty. for other purposes such as machine language routines or addi-
Actually, the buffer is not located absolutely at this area. tional sprite definitions.
The starting address of the RS-232 input buffer is determined
by the value in locations 200-201/$C8-$C9. The pointer loca-
tions are initialized to 3072/S0C00 by the RAMTAS routine
Sprite Pattern Storage Area
[$E093], part of the reset sequence. No other system routine 3584-4095/$0E00-$0FFF
changes the address in that pointer, so the buffer will be lo- This area is reserved by the system to hold sprite pattern defi-
cated here unless you explicitly move it. However, the buffer nitions. Each sprite pattern requires 64 bytes and must start at
can be moved to another free area of memory simply by an address which is an exact multiple of 64/$40. Other free
changing the address in the pointer. (The area selected must locations within the current video bank which meet these cri-
be visible in the bank 15 configuration.) teria can also be used for sprite pattern storage, but BASIC
If RS-232 communications are not used, this buffer area, sprite routines such as SPRSAV and SPRDEF assume that
along with the one at 3328-3583/$0D00-$0DFF, is available sprite patterns reside in this area. The sprite pointers for the
for other purposes such as machine language routines or addi- default screen memory position (2040-2047/$07T8-$07FF) are
tional sprite definitions. initialized during the BASIC cold-start sequence as follows:
Pattern area Pointer value Default sprite
3584-3647/$0E00-$0E3F 56/$38 0
RS-232 Output Buffer 3648-371l/$0E40-$0E7F 57/$39 1
3328-3583/$0D00-$0DFF 3712-3775/$OE80-$0EBF 58/S3A 2
The routines that transmit characters via the RS-232 interface 3776~3839/$0ECO-$0EFF 59/$3B 3
are executed during NMI interrupts. Characters are stored in 3840-3903/$OFOO-$OF3F 60/$3C 4
this area, usually by the BSOUT routine, while awaiting trans- 3904-3967/$0F40-$0F7F 61/$3D 5
3968-4O31/$0F80-$0FBF 62/$3E 6
mission. This is a circular buffer with no fixed beginning or 4032-4095/$0FCO-$0FFF 63/$3F 7
end. Location 2586/S0A1A holds the offset from the starting
address of the buffer to the next character waiting to be sent No system ROM routines change these settings. If your pro-
(called the head of the buffer). Location 2587/S0A1B holds gram doesn't require sprites, this area can be used for other
the offset to the next free position in the buffer (called the tail purposes such as to hold machine language routines.
of the buffer). The buffer is considered empty when the two
offset addresses are equal, and full when the buffer tail offset Programmable Key Definition String Area
is one less than the head offset.
Actually, the buffer is not located absolutely at this area. 4096-4351/$1000-$10FF
The starting address of the RS-232 output buffer is determined This 256-byte area is used to hold the strings for the ten pro-
by the value in locations 202-203/$CA-$CB. The pointer lo- grammable keys supported by the 128's screen editor routines:
cations are initialized to 3328/$0D00 by the RAMTAS routine F1-F8, SHIFT-RUN/STOP, and HELP. Each of the first 10
[$E093], part of the reset sequence. No other system routine
150 151
4096-4351 $1000-$!OFF $1133-$1134 4403-4404
bytes of the area (4096-4105/$1000-$1009) holds the length BASIC Working Storage
of one of the definition strings:
Location Key 4352-4607/$1100-$1IFF
4096/$1000 Fl
4097/$1001 F2 4352-4400 $1100-$1130 DOSSTR
4098/$1002 F3 DOS command assembly area
4099/$1003 F4 The BASIC statements that issue DOS commands—for ex-
4100/$1004 F5 ample, HEADER, COPY, CATALOG, and SCRATCH—use
4101/$1005 F6 this area to assemble the command string to be sent to the
4102/$1006 F7 disk drive.
4103/$1007 F8
4104/$1008 SHIFT-RUN/STOP 4401-4402 $1131-$1132 XPOS
4105/$1009 HELP
Bitmapped-screen pixel-cursor horizontal position
The remaining 246 bytes (4106-435l/$100A-$lOFF) are These locations hold the horizontal (x) coordinate of the cur-
available for definition strings. There is no particular limit on rent position of the pixel cursor on the bitmapped screen. The
the length of an individual definition string, except that the
range of values here depends on the scale factor currently in
combined length of all the definition strings cannot exceed 246
use. If scaling is not used, the value can be found in the range
bytes. The definition strings correspond to keys in the order
0-319. In any case, a value of zero specifies the left edge of
shown above. The offset to the first character in a particular
the screen. The value here is set to 0/$00 whenever the bit-
string is found by adding the lengths of all preceding defini-
tions. No special characters are used to separate the strings. It mapped screen is cleared, either by the SCNCLR routine or by
is possible for a key to have no associated definition string, in adding the clear parameter to a GRAPHIC statement. After
which case the length location for the key should be set to execution of any BASIC graphic statement, this location will
0/$00. The default definitions for the keys are as follows: hold the value of the final horizontal pixel position affected by
the operation. The value here can be set explicitly using the
Key Default definition LOCATE statement, which stores the specified horizontal posi-
Fl GRAPHIC tion in this location. If the DRAWTO form of the DRAW state-
F2 DLOAD" ment is used, the line will begin at the horizontal position
F3 DIRECTORY {RETURN} specified here.
F4 SCNCLR {RETURN}
F5 DSAVE" 4403-4404 $1133-$1134 YPOS
F6 RUN {RETURN}
F7 LIST {RETURN} Bitmapped-screen pixel-cursor vertical position
F8 MONITOR{RETURN} These locations hold the vertical (y) coordinate of the current
SHIFT-RUN/STOP DL"*{RETURN}RUN{RETURN} position of the pixel cursor on the bitmapped screen. The
HELP HELP{RETURN} range of values here depends on the scale factor currently in
These definitions, along with the corresponding length values, use. If scaling is not used, the value can be found in the range
are copied from locations 52904-52980/$CEA8-$CEF4 in 0-199. In any case, a value of zero specifies the top edge of
screen editor ROM during the Kernal CINT routine [$C07B]. In the screen. The value here is set to 0/$00 whenever the bit-
BASIC, the KEY statement can be used to change definitions. mapped screen is cleared, either by the SCNCLR routine or by
From machine language, the Kernal PFKEY routine [$FF65] (or adding the clear parameter to a GRAPHIC statement. After
screen editor KEYSET routine [$C021]) can be used. Pro- execution of any BASIC graphic statement, this location will
grammable keys are handled by a subroutine [$C6CA] within hold the value of the final vertical pixel position affected by
the screen editor keyscan routine. the operation. The value here can be set explicitly using the
152 153
4405-4406 $1135-$1136 $116D 4461
LOCATE statement, which stores the specified vertical posi- 4458 $ 116A SCALEM
tion in this location. If the DRAWTO form of the DRAW state- Scaling flag
ment is used, the line will begin at the vertical position This location indicates whether the scaling feature is to be
specified here. used when graphics are drawn on the bitmapped screen.
While this location contains 0/$00, scaling will not be used.
4405-4406 $1135-$1136 XDEST When the location contains any nonzero value, the horizontal
Final horizontal pixel position for graphics operations and vertical coordinates for all graphics routines will be scaled
These locations hold the calculated ending horizontal pixel- according to the values in locations 135-136/$87-$88 and
cursor position for BASIC graphics operations. The operation is 137-138/$89-$8A. This location is initialized to 0/SOO (scal-
complete when the value in locations 4401-4402/$1131-$1132 ing off) during the BASIC cold-start sequence, and also when-
equals the value here. ever the clear-screen parameter is included in a GRAPHIC
statement. The routine to execute the SCALE statement
4407-4408 $1137-$1138 YDEST [$6960] will store the first parameter following SCALE (0 or 1)
Final vertical pixel position for graphics operations here.
These locations hold the calculated ending vertical pixel-cursor
position for BASIC graphics operations. The operation is com- 4459 $116B WIDTH
plete when the value in locations 4403-4404/$1133-$1134 Line width for bitmapped graphics routines
equals the value here. The value here determines whether the lines drawn by BASIC
bitmapped graphics routines are to be standard width (indi-
4409-4455 $1139-$1167 cated when this location contains 0/$00) or double width (in-
Working storage for assorted graphics routines dicated when this location contains any nonzero value). The
BASIC graphics routines such as BOX, CIRCLE, DRAW, and value here is initialized to 0/$00 (normal width) during the
PAINT use various locations in this range to perform the cal- BASIC cold-start sequence. The routine to execute the WIDTH
culations necessary to plot the points for the figure being statement [$71B6] will store the width parameter minus 1 in
drawn. The MOVSPR routine also uses some of these loca- this location.
tions for sprite position calculations in those cases where the
sprite is moved relative to the pixel cursor. 4460 $116C FILFLG
BOX fill flag
4456 $ 1168 CHRPAG This location is used during the BOX routine [$62B7] to specify
Starting page for character pattern definitions whether the shape is to be open or filled. If the value here is
This location is used during the CHAR routine [$67D7] in the 0/$00 the shape will be open; otherwise, it will be filled. This
calculations to determine where character shapes are to be location is initialized to 0/$00 (open shapes) during the
placed on the bitmapped screen. The value here is the starting BASIC cold-start sequence. When a BOX statement is exe-
page of character memory. This location will hold the value cuted, the seventh parameter (paint) following the statement
from either 4588/$llEC or 4587/$llEB. will be copied here. If that parameter is omitted, it will default
to 0/$00.
4457 $1169 BITCNT
Bit counter for shape retrieval 4461 S116D BITMSK
This location is used during the GSHAPE routine [$658D] as a Bit mask value
counter for the bits to be read from each byte of the storage This location is used as a mask value to select individual bits
string. during the DRAW and SPRDEF routines.
154 155
4462 $116E $117C-$117D 4467-4477
4478-4565 $ 117E-$ 1 IDS SPRITE-DATA All locations in this range are initialized to 0/$00 during
Sprite movement control data the BASIC cold-start sequence. The warm-start sequence per-
The MOVSPR statement has an option to set sprites in motion forms the less dramatic initialization step of resetting all the
at a given angle and speed. These locations hold data concern- speed locations to 0/$00, which stops all sprite motion.
ing sprite motion. For moving sprites, the values here will be
used to generate position values that will be copied to the 4566-4582 $11D6-$11E6 VIC-SAVE
shadow registers at 4566-4582/$llD6-$llE6. The locations Shadows for VIC sprite position registers
are used as follows: The contents of these locations are copied into the VIC chip
Sprite 0 Sprite 1 Sprite 2 Sprite 3 sprite position registers (53248-53264/$D000-$D010) during
Speed 4478/$117E 4489/J1189 4500/$1194 4511/$119F each pass through the BASIC IRQ routine [$A84D]. As long as
Speed countdown 4479/$117F 4490/I118A 4501/$1195 4512/$11AO the BASIC IRQ routine is active, the VIC registers cannot be
Direction 4480/S1180 4491/$118B 4502/$1196 4513/$11A1
Horizontal increment (low) 4481/$1181 4492/$118C 4503/$1197 4514/$11AZ changed directly. Instead, you should store the desired register
(high) 4482/$1182 4493/$118D 4504/$1198 4515/$11A3 value in the corresponding shadow location. All locations in
Vertical increment (low) 4483/$1183 4494/$118E 4505/$1199 4516/S11A4 this range are initialized to 0/$00 during the BASIC cold-start
(high) 4484/S1184 4495/$118F 4506/$119A 4517/S11A5
Horizontal position (low) 4485/$1185 4496/$1190 4507/S119B 4518/$11A6 sequence. The values here can be set using the MOVSPR
(high) 4486/$1186 4497/S1191 4508/$119C 4519/$11A7 statement. The MOVSPR routine [$6CC6] sets the value here
Vertical position (low) 4487/$1187 4498/$1192 4509/$119D 4520/$11 A3 directly when a static sprite position is specified. When a mov-
(high) 4488/$1188 4499/S1193 4510/$119E 4521/$11A9
ing sprite is specified, the movement information is stored in
Sprite 4 Sprite 5 Sprite 6 Sprite 7 the table at 4478-4565/$117E-$llD5 and the values here are
Speed 4522/$! 1AA 4533/$llB5 4544/$llC0 4555/$llCB updated during each pass through the BASIC IRQ routine
Speed countdown 4523/$ 11AB 4534/S11B6 4545/$llO 4556/$llCC
Direction 4524/$ 11 AC 4535/$]1B7 4546/$11C2 4557/S11CD [$A84D]. The locations are used as follows:
(low) 4525/$ 11 AD 4536/$11B8 4547/S11C3 4558/$llCE
Horizontal increment (high) 4526/$llAE 4537/$11B9 4548/$llC4 4559/$llCF Location Register Function
(low) 4527/$llAF 4538/$ 11BA 4549/$llC5 4560/$11 DO 4566/$llD6 53248/$D0O0 Sprite 0 horizontal position
Vertical increment (high) 4528/S11B0 4539/S11BB 455O/$11C6 4561/$I1D1 4567/$llD7 53249/$D001 Sprite 0 vertical position
(low) 4529/$llBl 4540/$11BC 4551/$11C7 4562/$IlD2 4568/$llD8 53250/$D002 Sprite 1 horizontal position
Horizontal position (high) 453O/$11B2 4541/$11BD 4552/$HC8 4563/$llD3
(low) 4531/S11B3 4542/$llBE 4553/$llC9 4564/$llD4 4569/$llD9 53251/$D003 Sprite 1 vertical position
Vertical position (high) 4532/S11B4 4543/$llBF 4554/$llCA 4565/$ 11D5 4570/$1 IDA 53252/$D004 Sprite 2 horizontal position
4571/S11DB 53253/$D005 Sprite 2 vertical position
In addition to using the MOVSPR routine, the values here 4572/$llDC 53254/$D006 Sprite 3 horizontal position
can be set directly to set a sprite in motion. (The correspond- 4573/$llDD 53255/$D007 Sprite 3 vertical position
ing sprite must be enabled before the motion values have any 4574/$llDE 53256/$D008 Sprite 4 horizontal position
effect.) The speed value (0-15) determines how many times 4575/$llDF 53257/$D009 Sprite 4 vertical position
per IRQ interrupt the horizontal and vertical increment values 4576/$llE0 53258/$D00A Sprite 5 horizontal position
will be applied to the horizontal and vertical position values. 4577/$llEl 53259/$D00B Sprite 5 vertical position
If the speed value is 0/$00, the corresponding sprite will not 4578/$llE2 53260/$D00C Sprite 6 horizontal position
be moved. The speed value is copied to the countdown value 4579/$llE3 53261/$D0OD Sprite 6 vertical position
during each interrupt. The direction value can have one of the 458O/$11E4 53262/$D00E Sprite 7 horizontal position
following values: 4581/$11E5 53263/$D00F Sprite 7 vertical position
4582/S11E6 53264/$D010 Most significant bits of horizontal
Direction value Sprite motion position
0 x increasing, y decreasing
1 x increasing, y increasing
2 x decreasing, y increasing
3 x decreasing, y decreasing
159
158
4583-4584 $11E7-$11E8 $11EC 4588
4583-4584 $11E7-$11E8 statement for bitmapped screens (see location 4588/$llEC for
Shadows for VIC sprite-collision registers more information). CHAR will always begin using the charac-
During any pass through the BASIC IRQ routine [$A84D] ter set pointed to in location 4588/$llEC. To switch to the al-
where either or both of the sprite-collision latch flags {bits 1-2 ternate character set, the CHAR string must include character
of 53273/$D019) are found to be set to % 1 , the contents of code 14/$0E. Character code 142/$8E switches back to the
the corresponding VIC chip sprite-collision register will be re- default set. This location is initialized to 216/$D8 during
corded in these locations. For sprite-foreground collisions (in- BASIC cold start. That value selects the ROM lowercase/
dicated when bit 1 of the flag is set), any bits in the register at uppercase set at 55296/$D800 as the alternate character pat-
53279/$D01F which are set to %1 will also be set to %1 in lo- tern source. If you use a custom character set, you can change
cation 4584/$llE8. Likewise, for sprite-sprite collisions (indi- the value here to have CHAR use your new characters. How-
cated when bit 2 of the flag is set), the %1 bits in the register ever, the new character set must be visible in the bank 14
at 53278/$D01E will be recorded in location 4583/$llE7. memory configuration, since that is how the system will be
Thus, these locations will accumulate collision readings until configured when character pattern data is read.
they are cleared, rather than simply holding the most recent
collision values. The routine for the BASIC function BUMP 4588 $11EC UPPER-GRAPHIC
[$837C] returns values based on the contents of these loca- Starting page for default character set during CHAR
tions, rather than on the actual register contents. BUMP(l) re- The value here determines the starting page in system mem-
turns the sprite-sprite collision value in 4583/$llE7, and ory for the default set of characters used during the CHAR
BUMP(2) returns the sprite-foreground collision value in statement. The value here doesn't affect any statement other
4584/$llE8. Either location will be reset to 0/$00 after being than CHAR, and is used only when character shapes are being
read by BUMP. Both locations are also initialized to 0/$00 placed on a bitmapped screen. (When CHAR is used to place
during the BASIC cold-start sequence. characters on the text screen, the screen editor printing routines
are used instead.) For bitmapped screens, CHAR will always
4585-4586 $1lE9-$11EA begin using the character set pointed to here, regardless of the
Shadow for VIC light pen registers character set in use on the text screen. To switch to the alter-
During any pass through the BASIC IRQ routine [$A84D] nate character set (starting page in 4587/$llEB), the CHAR
where the light pen latch flag (bit 3 of 53273/$D019) is found string must include character code 14/$0E. Character code
to be set to % 1 , the contents of the VIC chip light pen regis- 142/$8E switches back to the character set pointed to here.
ters at 53267-53268/$D013-$D014 will be copied into these Thus, it is possible to mix the two character sets in a single
locations. The routine for the BASIC function PEN [$82AE] re- CHAR statement. This location is initialized to 208/$D0 dur-
turns values based on the contents of these locations, rather ing BASIC cold start. That value makes the ROM uppercase/
than on the actual register contents. PEN(O) returns the value graphics set at 53248/$D000 the default character pattern
in 4585/S11E9, multiplied by 2. PEN(l) returns the value in source. If you use a custom character set, you can change the
4586/S11EA. Either location will be reset to 0/$00 after being value here to have CHAR use your new characters. However,
read by PEN. Both of these locations are also initialized to the new character set must be visible in the bank 14 memory
0/$00 during the BASIC cold-start sequence. configuration, since that is how the system will be configured
when character pattern data is read.
4587 $11EB UPPER-LOWER
Starting page for alternate character set during CHAR
The value here determines the starting page in system mem-
ory for the alternate set of characters used during the CHAR
160 161
4589 $11ED $1208 4616
162 163
4617-4618 $1209-$120A $1212-$1213 4626-4627
164 165
4628-4629 $1214-$1215 $1223-$1228 4643-4648
4628-4629 $1214-$1215 TMPTXT as the seed for the next random number. Location 4635/$121B
Temporary text pointer storage for DO is initialized to 0/$00 during the BASIC cold-start routine.
This pair of locations is used to temporarily hold the CHRGET That is a change from previous Commodore models, where all
text pointer value (from 61-62/$3D-$3E) during execution of five bytes of the seed value were initialized. The zero byte has
the DO statement [$5FE0]. the effect of making the initial seed value 0, so the first ran-
dom number value generated after the computer is turned on
4630-4631 $1216-$1217 TMPLIN or after a reset will always be 1.07870447E-03.
Temporary line number storage for DO
This pair of locations is used to temporarily hold the current 4640 $1220 CIRCLE_SEGMENT
line number value (from 59-60/$3B-$3C) during execution of Degrees between segments for CIRCLE routine
the DO statement [$5FE0]. This location is used during the BASIC CIRCLE statement rou-
tine [$668E] to hold the number of degrees to turn for each
4632-4634 $1218-$121A USRPOK segment of the circle. The value here is set from the ninth pa-
USR function jump vector rameter in the CIRCLE statement, and defaults to 2 if that pa-
The BASIC function USR calls a machine language routine, rameter is omitted.
like SYS, but it also allows a numeric value to be passed to
and from the ML routine. The routine in BASIC ROM that ex- 4641 $1221 DEJAVU1
ecutes USR ends with a JMP $1218. Location 4632/$1218 Although Commodore literature states that this location holds
contains 76/$4C, the machine language JMP instruction. Loca- a value relating to the reset status, no reference to this location
tions 4633-4634/$1219-$121A should contain the address of occurs in any ROM routine.
the target machine language routine (in the usual Iow-
byte/high-byte format). You must explicitly load these loca- 4642 $1222 TEMPO-RATE
tions with the address of the target routine before you use Tempo setting for PLAY statement
USR. This location is initialized to 32040/$7D28 during The value here determines the tempo for notes played by the
BASIC cold start. This is the address of the routine that issues BASIC PLAY statement. The value here is subtracted from the
the ILLEGAL QUANTITY ERROR message, which is what sound duration value for each voice (in locations 4643-4648/
you'll get if you use USR without changing locations $1223-$1228) during each pass through the BASIC IRQ rou-
4633-4634/$1219-$121A. Refer to Chapter 5 for more infor- tine. The larger the value here, the faster the duration de-
mation on passing values to and from the called routine. creases and the faster each note plays. The value here is
initialized to 16/$10 during the SID initialization routine
4635-4639 $121B-$121F RNDX [$4112], part of both the BASIC cold start and warm start se-
Random number seed value quences. In BASIC, the TEMPO statement can be used to
This five-byte area holds the seed value for BASIC'S random- change the value here.
number-generator routine [$8434]. When a positive argument
is supplied, the RND routine generates the next random num- 4643-4648 $1223-$1228 VOICES
ber by performing calculations and manipulations with the Durations for currently active notes
value here. The generated values aren't really random—any These locations hold the durations of the current PLAY state-
given seed value here will always produce the same result. ment notes for each of the SID chip voices:
However, the process is sufficiently complicated that the re- Voice 0: 4643-4644/$1223-$1224
sults aren't easily predictable. Whenever any random number Voice 1: 4645-4646/$1225-$1226
is generated, the resulting value is stored here for possible use Voice 2: 4647-4648/$1227-$1228
166 167
4649-4650 $1229-$122A $123O-$1232 4656-4658
Bit 7 of each of the high bytes (4644/$1224, 4646/$1226, and 4652 $122C SHARP
4648/$1228) is used to indicate whether a note is currently Sharp/flat flag
being played by that voice. The voice is active when that bit is The value in this location holds a value that indicates whether
%0. The duration value for each active voice is decremented the current note will be either sharp or flat. The location nor-
by the tempo value specified in location 4642/$1222 during mally holds 0/$00 for natural notes. When a # character is
each pass through the BASIC IRQ routine [$A84D]. When a found in the PLAY string, this location will be set to l/$01 to
duration is decremented below $0000, the high byte will roil indicate that the next note should be sharp. When a $ charac-
over to $FF, which will set bit 7 to % 1 , marking the end of the ter is found in the string, this location will be set to 255/$FF
note. At this point, the gate bit for the voice will be turned off, to indicate that the next note should be flat.
stopping sound output for that voice. Large tempo values
cause the value here to decrease more rapidly, increasing the 4653-4654 $122D-$122E PITCH
speed at which notes are played, while small tempo values in-
crease the note time. Frequency for current note
When the PLAY statement prepares a note, the frequency for
The high bytes for all three voices are set to 255/$FF by the note is calculated in these locations before being trans-
the SID initialization routine [$4112], part of both the BASIC ferred into the SID chip registers for the specified voice. The
cold start and warm start sequences. This makes all voices ini- frequency is calculated by loading a base frequency for the
tially inactive. When the PLAY statement plays a note, the du- specified note from the table at 28665-28688/$6FF9-$7010,
ration for that note will be copied from 4649-4650/$ 1229-$122A adjusted for the octave specified in 4651/$122B. If the flag at
into the slot for the voice specified for that note. 4652/$122C indicates that the note is to be sharp or flat, the
frequency is adjusted accordingly.
4649-4650 $1229-$122A NTIME
Duration of current note 4655 $122F VOICE
When the PLAY statement prepares a note, the duration for Voice number for current note
the note is first calculated in this location, then transferred to The value in this location specifies which voice will be used to
the proper slot in 4643-4648/$1223-$1228. The value here is play the next note. The value here is set to 0/$00 by the SID
set to 288/$0120, the value for a quarter note, by the SID ini- initialization routine [$4112], part of both the BASIC cold start
tialization routine [$4112], part of both the BASIC cold start and warm start sequences. This selects voice 0 as the default
and warm start sequences. voice. The value here will remain in effect until changed by a
V parameter in the PLAY string. The parameter value will be
4651 $122B OCTAVE reduced by 1 to convert the BASIC voice number (1-3) to a
Octave for current note VIC voice number (0-2).
The value in this location determines the octave for the cur-
rent notes played by the PLAY statement. This value will af- 4656-4658 S1230-S1232 WAVE
fect the calculation of the frequency for the notes. The value Waveforms for current notes
here is set to 4/$04, the octave containing middle C, by the The values in these locations determine which waveforms will
SID initialization routine [$4112], part of both the BASIC cold be used for each of the three voices:
start and warm start sequences. The octave value here remains
in effect until changed by an O parameter in the PLAY string. Voice 0: 4656/$1230
Voice 1: 4657/$1231
Voice 2: 4658/$1232
168 169
4659 $1233 $123F-$1270 4671-4720
These locations hold the waveform value for the instrument 4667-4669 $123B-$123D TONVAL
specified for the voice. All three voices are initialized to the Envelope parameters for current instrument
default value for instrument 0. This selects a default pulse The current parameters for the specified instrument are read
waveform for all three voices. The value here remains in effect from the instrument table into these locations at the beginning
until changed by a T parameter in the PLAY string. The T pa- of the ENVELOPE routine [$7OC1]:
rameter causes the value for the current voice to be changed to
the waveform value for the specified instrument from the table Attack/decay: 4667/$123B
at 4671-4720/$123F-$1270. Sustain/release: 4668/$123C
Waveform: 4669/$123D
4659 $1233 DNOTE If the ENVELOPE statement specifies new values for any of
Dotted-note flag these parameters, the new values replace the original values
The value in this location determines whether the next note here. The values here are then copied back into the table en-
will be normal or "dotted." Dotted notes play IV2 times as tries for the specified instrument number.
long as a standard note. This location normally holds 0/S00,
but will be set to 35/$23 if a period (.) is found in the play 4670 $123E PARCNT
string. In this case, the duration of the next note will be in- Index into instrument table for current instrument
creased by 50 percent. This value is used during the ENVELOPE routine [$7OC1] to
hold the index to the current set of instrument parameters.
4660-4663 $1234-$1237 FILTSAV
Temporary storage for filter parameters 4671-4720 $123F-$1270
The filter parameters are copied here from 4721-4722/ Instrument parameter tables
$1271-$1272 at the beginning of the FILTER statement rou- This area is used to hold the envelope parameters for the ten
tine [$7046], The filter parameter manipulations are then per- defined instruments supported by the PLAY statement [$6DE1]:
formed on these locations, and the results are copied back to Instrument Attack/ Sustain/ Waveform Pulse width
Decay Release low byte high byte
the working storage area. 0 4671/S123F 4681/S1249 4691/S1253 4701/$125D 4711/S1267
1 4672/$1240 4682/$124A 4692/$1254 4702/$125E 4712/S1268
4664 $1238 FLTFLG 2 4673/$1241 4683/$124B 4693/S1255 4703/$125F 4713/$1269
4674/$1242 46S4/S124C 4694/$1256 4704/S1260 4714/$126A
Filter type index 4 4675/$1243 4685/$124D 4695/$1257 4705/J1261 4715/S126B
This location is used as a mask value to select individual filter 5 4676/$1244 4686/$124E 4696/$1258 4706/S1262 4716/$126C
6 4677/S1245 4b87/$124F 4697/S1259 4707/S1263 4717/$126D
control bits when evaluating the FILTER statement parameters. 7 4678/S1246 4688/51250 469S/$1Z5A 4708/$1264 4718/S126E
8 4679/$1247 4689/$125I 4699/S125B 4709/$1265 4719/S126F
4665 $1239 NIBBLE 9 4680/S1248 4690/$1252 4700/S125C 4710/$1266 4720/S1270
Temporary storage All three voices are initially assigned the envelope parameters
This location is used as working storage by the FILTER and for instrument 0. These settings remain in effect until changed
ENVELOPE routines. with a T parameter in the PLAY string.
The values for any table entry can be changed using the
4666 $123A TONNUM ENVELOPE statement. Default instrument table values are
Current instrument number copied into this area from a table in ROM at 28689-28728/
This location will hold the instrument number specified in the $7011-$7038 during the SID initialization routine [$4112], part
most recent ENVELOPE statement. of both the BASIC cold start and warm start sequences. The
default values are as follows:
170 171
4721-4722 $1271-$1272 $1276-$1278 4726-4728
172 173
4729-4734 $1279-$127E $1282-$12A2 4738-4770
SID initialization routine [$4112], part of both the BASIC cold 4737 $1281 SOUND-VOICE
start and warm start sequences. A location set to 255/SFF will Voice for current SOUND statement
be reset to 0/$00 after COLLISION processing in the GONE The value in this location specifies which group of entries in
routine [$4A9F]. the following table should be loaded with the current SOUND
parameters. The value here is set to the value of the first pa-
4729-4734 $1279-$127E INT_ADR rameter in the SOUND statement, minus 1 to convert the
Target line numbers for COLLISION BASIC voice number (1-3) into a SID voice number (0-2).
If the trapping of sprite collisions or light pen latches is en-
abled, a BASIC subroutine will be called (effectively a GOSUB) 4738-4770 $1282-$12A2
whenever one of the selected events occurs. These locations Table of SOUND statement settings
are used to hold the number (in low-byte/high-byte integer
format) of the starting BASIC program line of the subroutine These locations hold the current SOUND parameters for the
to be called. (The subroutine should end with a RETURN three SID chip voices:
statement.) The values here can be set with the COLLISION Parameter Voice 0 Voice 1 Voice 2
Duration (low) 4738/$1282 4739/$1283 4740/$1284
statement. (high) 4741/$1285 4742/$2286 4743/$1287
Low byte High byte Collision type Frequency (low) 4744/S1288 4745/$1289 4746/$128A
4729/$1279 4732/$127C sprite-sprite (high) 4747/5128B 4748/$128C 4749/$128D
473O/$127A 4733/$127D sprite-foreground Minimum frequency (low) 4750/$128E 4751/$128F 4752/$1290
(high) 4753/$1291 4754/$I292 4755/$1293
4731/$127B 4734/S127E light pen Step direction 4756/$1294 4757/$1295 4758/$1296
Step size (low) 4759/51297 4760/51298 4761/$1299
4735 $127F INTVAL (high) 4762/$129A 4763/$129B 4764/$129C
Collision enable flag Current frequency (low) 4765/$129D 4766/$129E 4767/$129F
(high) 4768/$12A0 4769/$12Al 4770/$12A2
Bits 0-2 of this location indicate the collision types for which
trapping is currently enabled: Bit 7 of each of the duration high-byte values (locations
Bit Collision type 4741-4743/$1285-$1287) is used to indicate whether any
0 sprite-sprite SOUND statement is active for the corresponding voice. If the
1 sprite-foreground bit is %0, the voice is assumed to have an active sound, and
2 light pen the current frequency value for the voice will be copied into
Trapping is enabled if the bit is set to % 1 . Enabling trapping the SID chip frequency registers during each pass through the
will allow the corresponding collision type to be recorded in BASIC IRQ routine [$A84D]. See Chapter 5 for a discussion of
the flags at 4726-4728/$1276-$1278. Bits 3-7 of this location the other SOUND effects, such as frequency sweeps. Also dur-
are unused. The value here is reset to 0/$00 during the BASIC ing each pass through the interrupt routine, the duration value
cold-start sequence. This disables all COLLISION branching. for each active voice will be decremented. When the value is
decremented below $0000, the high byte will roll over to
255/$FF, setting bit 7 to % 1 , which marks the end of the
4736 $1280 COLTYP sound. At this point the gate bit for the voice will be set to %0
Collision type index to turn off the sound.
The value here is used during the COLLISION routine [$7164] Each of the duration high-byte locations will be set to
to hold an index into the line number table at 4729-4734/ 255/$FF during the SID initialization routine, part of both the
$1279-$127E. BASIC cold start and warm start sequences. This will turn off
174 175
4771-4776 $12A3-$12A8 $12F6-$12F9 4854-4857
SOUND output for all three voices. The values in these loca- 4787-4790 $12B3-$12B6 WINDOW_TEMPS
tions are updated when the contents of 4771-4776/$ 12A3-$12A8 Temporary parameter storage for WINDOW statement
are copied to the entries for the specified voice during execution When the WINDOW statement [$72CC] is executed, the pa-
of the SOUND statement [$71EC]. rameter values associated with the statement are stored in
these locations before the screen editor WINDOW routine
4771-4776 $12A3-$12A8 [$C02D] is called to actually set the new window margins.
Parameters for most recent SOUND statement Location Parameter
These locations are used to assemble the parameters for the 4787/$12B3 left column
current SOUND statement. The SOUND statement must in- 4788/$12B4 top row
clude voice number, frequency, and duration parameters. The 4789/$12B5 right column
remaining parameters are optional; if they are omitted, default 4790/$12B6 bottom row
values are supplied. The base frequency value is initialized to
the specified starting frequency. The locations and default val- 4791-4806 $12B7-$12C6
ues are as follows: Filename buffer for DOS support commands
Parameter Locations Default value The routine which handles the BASIC 7.0 DOS support com-
Duration 4771-4772/$12A3-$12A4 mands such as SCRATCH and RENAME copies the filename
Frequency 4773-4774/$12A5-$12A6 portion of the command here temporarily while the remainder
Minimum frequency 4775-4776/$ 12A7-S12A8 0/$0000 of the command is being processed. Once the command is set
Step direction 4777/$12A9 0/$00 (sweep up) up, the filename here is copied into the DOS command buffer
Step size 4778-4779/$ 12AA-S12AB 0/$0000 (no sweep)
Base frequency 4780-4781/$12AC-$12AD at 4352-4399/$1100-$112F.
Pulsewidth 4782-4783/$12AE-$12AF 2048/S0800
Waveform 4784/$12B0 2/$02 (pulse) 4791-4853 $12B7-$12F5 SAVRAM
After all the parameters for a SOUND statement have Sprite pattern storage
been evaluated and assembled here, the values are transferred These locations are used during the SPRDEF statement routine
to the entries in the table at 4738-4770/$1282-$12A2 for the [$7372] to hold the original sprite pattern while a sprite is be-
specified voice. The base frequency value is used as the begin- ing defined. If the STOP key is pressed to cancel the current
ning current frequency value. modifications, the pattern definition here will be restored to
the definition area for the sprite. The first 63 of these locations
4785 $12B1 POT_TEMP_1 are also used during the SPRSAV routine [$76EC] to hold the
Temporary storage for POT and PEN routines sprite pattern to be transferred to a string variable.
This location is used as temporary storage during the routines
to perform the BASIC functions POT [$824D1 and PEN 4854-4857 $12F6-$12F9
[$82AE]. Sprite pattern suffix
During the SPRSAV routine [$76EC], these locations are ini-
4786 $ 12B2 POT_TEMP_2 tialized with the pattern $17 $00 $14 $00. When a sprite pat-
Temporary storage for POT routine tern is saved in a string variable, these bytes are appended to
During execution of the POT function routine [$824D], the the sprite pattern in 4791-4853/$12B7-$12F5 before the data
potentiometer reading from the SID chip register is stored here is transferred to the string pool. Two bytes are needed as the
temporarily while the paddle buttons are being read. tag for the variable, but exactly what this four-byte pattern is
intended to achieve is unclear.
176 177
4858 $12FA $13OO-$1BFF 4864-7167
184
beyond the starting address in 45-46/$2D-$2E. An OUT called "reserved" in Commodore literature). This 2304-byte
OF MEMORY error occurs if the address in 4624-4625/ area is the largest unused area of protected RAM in the 128,
$1210-$1211 reaches the value in 4626-4627/ $1212-$1213. and it is becoming extremely popular with 128 ML program-
The ending address pointer is set after a BASIC LOAD [$912C], mers—much like the $C000 block in the Commodore 64. You
and the BASIC SAVE routine [$9112] uses the values in the can expect to see many ML programs using this area.
starting and ending address pointers as the starting and end- Other, shorter blocks are also available if certain BASIC
ing address for the block of memory to be saved. features are not used. If tape is not used, the 256 bytes at
The address in the pointer at locations 47-48/$2F-$30 2816-3071/$0B00-$0BFF are available. However, unlike other
marks the start of scalar (nonarray) variables in bank I. The free blocks, this page may be overwritten during a reset be-
pointer is initialized to 1024/$0400 during the BASIC cold cause disk boot sectors are read into this area. Thus, the time-
start routine. A pointer at 49-50/$31-$32 marks the end of honored Commodore tradition of using the cassette buffer for
scalar variables and the beginning of arrays; another pointer at short ML routines is less suitable in the 128. (It's annoying to
51-52/$33-$34 marks the end of arrays and the beginning of have to reload your routine after each reset.) If your program
free memory in block 1. Both of these pointers are reset to the doesn't use RS-232 communications, the two RS-232 buffers at
value in 47-48/$2F-$30 during the BASIC CLR routine. The 3072-3583/$0C00-$0DFF provide a 512-byte workspace. This
pointer at 57-58/$39-$3A holds an address which is one byte is probably the best area for short ML routines that you wish
beyond the highest address of free memory in block 1. It is to use in conjunction with BASIC. (Unlike the cassette buffer,
initialized during BASIC cold start to point to 65280/$FF00. this area survives reset intact.) If your program does not use
The free memory in block 1 is used to hold strings of all sprites, the 512-byte sprite definition area at 3584-4095/
types—constants, variables, and arrays. The string pool starts $0E00-$0FFF is also available. Of course, if your program uses
at the top of free memory and is filled downward toward the neither tape nor RS-232 nor sprites, you can use the full 1280
bottom of free memory indicated in 51-52/$33-$34. The bytes at 2816-4095/$0B00-$0FFF or any subsection thereof.
pointer at 53-54/$35-$36 marks the current address of the
To use a large ML program in conjunction with BASIC,
bottom of the string pool. That pointer is reset to the value in
there is an easy way to reserve over UK of protected RAM.
57-58/$39-$3A by the BASIC CLR routine. An OUT OF
However, this technique works only if neither the BASIC nor
MEMORY error occurs when the value in 53-54/$35-$36
the ML program requires high-resolution graphics. The trick is
reaches the value in 51-52/$33-$34.
to use the BASIC GRAPHIC statement to set aside a high-
resolution screen area at 7168-16383/$lC00-$3FFF. As men-
Reserving RAM tioned above, this area remains allocated until a GRAPHIC
There are occasions when you will want to divert an area of CLR statement is executed. Simply begin your BASIC program
RAM from its normal usage. For example, you may need to set with a line like GRAPHIC 1:GRAPHIC 0 (or GRAPHIC
aside space for a machine language routine, an alternate 1:GRAPHIC 5 if you want to use the 80-column display).
screen display, or a data buffer. For machine language (ML) Then BLOAD the machine language program into the reserved
programming, you can use any area of RAM if you are willing area. In addition to the 9K screen area, you can also use the
to learn the intricacies of the 128's banking scheme. Other- contiguous unused area just below, at 4864-7167/$1300-$lBFF.
wise, it's best to restrict your programming to certain known If you want to use a machine language program in conjunction
areas. For a machine language routine to be used in conjunc- with BASIC and high-resolution graphics, you'll have to resort
tion with a BASIC program, you'll need to select an area to bank-switching techniques if the program is too large to fit
which BASIC doesn't normally use, or to take away some in the unused area at 4864/$1300.
memory that otherwise would be used for program text or It's possible to reserve space above or below either the
variable storage. As noted in Chapter 3, locations 4864-7167/ BASIC or variable/string areas. To reserve space below the
$13OO-$1BFF are currently unused (even though they are BASIC program text, increase the value in the start-of-BASIC
186 187
pointer at 45-46/$2D-$2E by the number of bytes you want You can also reserve space in block 1, either above or be-
to reserve. (To reserve an even number of 256-byte pages, you low the variable/string area. To reserve space below variables,
need only change the value in 46/$2E.) Two other steps are add a value corresponding to the number of bytes to be re-
also necessary: BASIC requires a zero byte below the first lo- served to the address in the pointer at 47-48/$2F-$30, (As
cation in its program text space, and a NEW operation is re- with the other pointers, you can simply increase the value in
quired to reset other important memory pointers. For example, 48/$30 if you are reserving an even number of 256-byte
to reserve three pages (768 bytes) below the normal start of pages.) This step must be followed by a BASIC CLR statement
BASIC, you would use a statement like this: to reset other variable pointers, so it should be performed
POKE 46,31:POKE 31*256,0:NEW early in the program (CLR erases all variable values). The fol-
After this statement is executed, the area at 7168-7935/ lowing line reserves an additional IK at the bottom of variable
$1COO-$1EFF is protected from BASIC until the next time the space, locations 1024-2047/$0400-$07FF in block 1:
BASIC cold start routine is performed (normally during the 100 POKE 48,8:CLR
next reset sequence). The pointer value is unaffected by Once established, the reserved area will remain intact until the
RUN/STOP-RESTORE. This technique is less useful when a next time the BASIC cold start routine is executed, normally
high-resolution screen area is allocated. In that case, the start at the next reset. The setting is unaffected by RUN/STOP-
of BASIC is moved to 16384/$4000. The technique for reserv- RESTORE.
ing space at the start of BASIC still works, but the reserved Since this reserved RAM is in block 1, it can't be used for
memory will lie above 16383/$3FFF, which is the highest ad- ML routines as easily as the RAM from block 0. There is no
dress seen as RAM in bank 15—the bank in which Kernal standard bank configuration that makes BASIC and Kernal
ROM is visible and to which BASIC defaults. Thus, a routine ROM visible in conjunction with block 1 RAM. Of course, it is
above that boundary will be invisible unless you tinker with
the MMU configuration register. possible to access Kernal or BASIC routines indirectly by using
the JSRFAR or JMPFAR routine. One use for a reserved area in
Space can be reserved at the top of the BASIC program block 1 would be for an alternate 40-column screen. See the
area by reducing the value in the pointer at 4626-4627/ entry for the MMU RAM configuration register (54535/$D506)
$1212—$1213 by the desired number of bytes. (Again, if you information on using block 1 for VIC-II screen memory.
wish to reserve an even number of 256-byte pages, you can To reserve space above strings, subtract a value cor-
simply reduce the value in 4627/$l213.) No additional steps responding to the number of bytes to be reserved from the ad-
are required other than changing the pointer value. This tech- dress in the pointer at 57-58/$39-$3A. (As with the other
nique was often used in the Commodore 64 to reserve space pointers, you can simply increase the value in 58/$3A if you
for machine language routines; its usefulness is more limited are reserving an even number of 256-byte pages.) This step
in the 128 because of the 16384/$4000 boundary of RAM visi- must also be followed by a BASIC CLR statement to reset
ble in bank 15, which was mentioned above. To easily use the other string pointers, so it should be performed early in the
reserved area for an ML routine in conjunction with BASIC, program (CLR erases all variable values). The following line
the top of memory must be lowered sufficiently to make at reserves 31K at the top of string space, locations
least a portion of the reserved area appear below the bound-
ary of RAM visible in bank 15; this dramatically reduces the 32768-65279/$8000-$FEFF in block 1:
amount of memory available for program text. It's not even 100 POKE 58,128:CLR
possible when a high-resolution screen area is allocated. The Once established, the reserved area will remain intact until the
technique can, however, be useful for setting aside an area in next time the BASIC cold start routine is executed—normally
block 0 for a buffer, a reserved area of memory for data at the next reset. The setting is unaffected by RUN/STOP-
storage. RESTORE. As mentioned above, this area can't be easily used
for machine language routines since it is in block 1. One ap-
188 189
propriate use for a reserved area here would be for a data important routines and vectors. The MMU configuration and
buffer—to hold downloaded text in a telecommunications pro- load configuration registers always appear in the lower five
gram, for example. bytes of this area, locations 65280-65284/$FF00-$FF04. They
should never be disturbed unless you know the effect of the
Using ML Without BASIC values you are storing there (see Chapter 8 for more infor-
You have several options when using ML programs alone, mation on the MMU). You should also exercise care when
without BASIC. The simplest, if your program is less than 9K changing the contents of locations 65285-65348/$FF05-$FF44
(9216 bytes) long, is to leave the system in its default bank 15 in either RAM block, as these areas contain copies of the inter-
configuration and use the visible area of block 0 RAM at rupt and reset handling routines. (These areas are initialized
7168-16383/$lC00-$3FFF. (If you need a few more bytes, by the Kernal RESET routine [$E000].) If an interrupt or reset
you can stretch the start of the program down to the bottom occurs while the system is configured for a bank where Kernal
of the reserved area at 4864/$1300.) With this setup, you have ROM is not visible—bank 0 or 1, for example—a crash will
full access to the I/O chip registers and all the routines in occur if the area in the visible RAM block does not contain a
BASIC and Kernal ROM. routine to redirect the reset or interrupt to a proper handling
If you need more space, but still want access to Kernal routine. See the entries for these addresses in Chapter 9,
"Kernal ROM," for more information.
routines, you can change the settings of bits 1-3 of the MMU
configuration register to switch out BASIC ROM. In this case, Free space in this page includes the 181 bytes at locations
you'll have access to over 43K of contiguous RAM, locations 65349-65529/$FF45-$FFF9 in block 0 and the 176 bytes at
4864-49151/$1300-$BFFF. If you want to use a high-resolution 65349-65524/$FF45-$FFF4 in block 1. However, locations
screen in conjunction with your ML routine, it's easiest to set 65488-65519/$FFD0-$FFEF in block 0 will be overwritten
up the screen in its normal location (7168-16383/$1COO-$3FFF). whenever the computer is reset. As mentioned in Chapter 1,
This means that—if your program is too long to fit below the the Z80 microprocessor has control briefly after a reset or
screen areas—you'll need to switch out BASIC to have some when the computer is first powered on. The initialization steps
RAM visible with Kernal ROM. (You could still use the Kernal performed by the Z80 include copying two routines into block
JSRFAR routine to access BASIC routines—if you wanted to 0 RAM. One, at 65488-65503/$FFD0-$FFDF, is an 8502 ma-
chine language routine to surrender control to the Z80; the
use some of the graphics drawing routines, for example.) other, at 65504-65519/$FFE0-$FFEF, is a Z80 machine lan-
Although it is possible to set up a custom MMU configu- guage routine to surrender control to the 8502. These routines
ration that makes block 1 RAM visible with either BASIC or have no use in 128 mode—they can be used only in CP/M
Kernal ROM (or both), there's rarely a need for such gyrations. mode—but they are recopied to block 0 during each reset.
It's usually easiest to locate your executable machine language {Actually, there is one situation where disturbing these routines
in block 0 and use block 1 for data storage. can cause a problem. If you overwrite the routine at 65488/
Several obscure techniques are available to squeeze a few $FFD0 and then attempt to start CP/M with a BASIC BOOT
more bytes out of the 128. For example, you can gain access to command, the system will crash. The machine language in the
the lowest IK of block 1 RAM, which is normally covered by CP/M boot sector expects that routine to be intact.)
the common area from block 0, by changing the value in the
MMU RAM configuration register (54534/$D506). See the dis- Locations 65525-65529/$KFF5-$FFF9 in block 1 have a
cussion of the MMU in Chapter 8 for details. special use. The first three bytes, locations 65525-65527/
$FFF5-$FFF7, are an initialization signature; after the Kernal
Page 255/$FF RESET routine [$E000] has been performed at least once, these
The highest page of memory, locations 65280-65535/ locations will contain the character codes for the letters CBM.
$FFO0-$FFFF, in each RAM block is normally unused by
BASIC and contains a few bytes of free RAM as well as some
190 191
As long as the signature locations contain these codes, the ini- least the IOINIT and CINT routines, and it should also disable
tialization test subroutine will take an indirect jump to the ad- RUN/STOP-RESTORE by redirecting the NMI vector. Here is
dress specified in locations 65528-65529/$FFF8-$FFF9, called a short example:
the system vector or soft reset vector. This vector normally
points to 57892/$E224 in Kernal ROM, a routine that does ocoo LDA #$F8 ;Use Kernal INDSTA routine to
0C02 STA $C3 change system reset vector
nothing more than reinitialize the signature and vector. You 0C04 LDA #$FF ; in bank 1 to point to the
can change the vector to point to a routine of your own to add OC06 STA $C4 ; routine at $0C28
additional steps to the reset sequence or to initiate an entirely 0C08 LDA #$C3
new reset sequence. One restriction applies: The routine you OCOA STA $02B9
specify in the vector must be visible in the bank 15 configura- OCOD LDA #$28
tion since that is how the system is set up when the jump OCOF LDX #$01
through the vector is taken. 0C11 LDY #$00
When tapping into the RESET routine, you need to be 0C13 JSR $FF77
aware of what has happened before the vector jump is taken 0C16 LDA #$0C
and what hasn't happened yet. Before entering the subroutine 0C18 LDX #$01
that takes the jump through the vector, the RESET routine 0C1A INY
0C1B JSR $FF77
[$E000] resets the stack pointer to the top of the stack, config- 0C1E LDA #$33 ;Change the INMI indirect vector
ures the system for bank 15, resets the other MMU registers to 0C20 STA $0318 ; to point to the interrupt return
their default values, and recopies the common routines to 0C23 LDA #$FF ; routine (disables RUN/STOP-
65285-65348/$FF05-$FF44, 674-763/$02A2-$02FB, and 0C25 STA $0319 ; RESTORE)
1008-1020/$03F0-$03FC. However, the initialization routines OC28 JSR $FF84 ;Kernal IOINIT routine
IOINIT, RAMTAS, RESTOR, and CINT are normally called 0C2B JSR $cooo ;Kernal CINT routine
after the return from the jump. This means that you can't use 0C2E LDX #$00 ;Loop to print message repeatedly
the vector diversion to change default indirect vector settings 0C30 LDA $0C40,X ; text at $0C40
or to alter screen parameters if your routine ends with RTS to 0C33 BEQ $0C2E
return to the normal reset sequence. It also means that when 0C35 JSR $FFD2
you use the vector to substitute your own reset sequence, you 0C38 INX
may need to call one or more of these subroutines to complete 0C39 BNE $0C30
system initialization. At least the IOINIT routine [$E109] or ;Text for message
some equivalent initialization routine is necessary, since the >0C40 49 20 43 41 4E 27 54 20
>0C48 42 45 20 53 54 4F 50 50
reset signal generated by pressing the RESET button also re- >0C50 45 44 21 0D0DO0
sets the VIC and VDC (8563) video chips, clearing all chip
registers to zero. IOINIT initializes the video chip registers to Use J F0C00 {from the monitor) or BANK 15:SYS 3072
their standard settings. (from BASIC) to set the new pointer values and start the rou-
tine. Once started, it cannot be stopped with either reset or
One interesting use of this vector is to make a machine RUN/STOP-RESTORE. Obviously, you should make sure
language program unstoppable by anything short of turning that your ML program is fully debugged—and be sure that
off the computer. To accomplish this, change the vector to you have a backup copy, just in case it isn't—before you use
point to the initialization routine of the program to be made this technique to make the program unstoppable.
unstoppable. That initialization step should include calls to at The highest six addresses in each RAM block, locations
65530-65535/$FFFA-$FFFF, contain copies of the processor
192 193
reset and interrupt vectors. This area is initialized during the
reset sequence, and, like the handling routines to which these
vectors point, these vector addresses should be changed with
care. The system will crash if a RAM vector does not contain
the address of a valid handling routine when an interrupt or
reset occurs while that block is visible. See the entries for
these addresses in Chapter 9 for more information on the pro-
cessor vectors.
194
BASIC ROM
The Commodore 128's BASIC 7.0 occupies the 28K of ROM
between 16384-45055/$4000-$AFFF. That represents signifi-
cant growth from the BASIC 2.0 of the Commodore 64, which
filled only about 9K. The expansion is the result of the addi-
tion of a variety of graphics, sound, and sprite statements, as
well as enhanced commands for disk operations. Because
BASIC is so large, it's not practical to provide a detailed de-
scription of every routine—that would fill another book. In-
stead, the entry points to most of BASIC'S important routines
are listed, with short explanations of what the target routines do.
Adding to BASIC
Even with all the added features of BASIC 7.0, you may find
it lacking and wish to modify BASIC to add new commands.
One common way to do this in the Commodore 64 is to copy
BASIC ROM into RAM, then modify and use the RAM-based
version. This scheme can't be used on the 128, even though it
does have RAM under BASIC ROM like the 64. While it's pos-
sible to copy BASIC into ROM, there's no easy way to keep a
RAM-based version of BASIC executing in RAM. The bank-
switching routines in 128 BASIC ROM keep the system con-
figured for banks 14 or 15, where BASIC ROM is visible,
while BASIC routines are being executed.
The formal method of adding new statements or functions
is to tap into the indirect vectors at 780-785/$030C-$0311
and 764-765/$02FC-$02FD. This allows you to add new
statements or functions that use the two-byte extended tokens.
Currently, extended statement tokens 39-255/$27-$FF and
extended function tokens ll-255/$0B-$FF are unused and
thus available for your additional keywords.
Three separate steps are required to add a new keyword.
You must provide for it to be tokenized, detokenized (listed),
and executed. The indirect vector at 780-781/$030C-$030D
lets you patch into the CRUNCH routine to tokenize your new
extended token keywords. The vector at 782-783/
$030E-$030F lets you patch into the IQPLOP routine to
detokenize these new keywords when a line containing a new
197
keyword is listed. The other two vectors allow you to patch 1647 CLC
into the statement and function execution routines to provide 1648 BCC $164D ;Exit with carry clear if keyword found
for the handling of the new keywords (784-785/$0310-$0311 164A SEC
164B LDA $02 ;Restore text character
for statements and 764-765/$02FC-$02FD for functions). The 164D JMP $4321 .Return to ICRNCH routine
following example shows the addition of a statement and a >1650 53 54 4F 52 C5 00 ;STORE
function. The statement, STORE, can be used to store values >1656 52 41 C4 00 ;RAD
in the VDC chip internal registers (see Chapter 8 for details of ;List (detokenize) new keywords
the VDC chip). The format of the statement is STORE register, 165A CPX #$00 ;Was this statement or token?
165C BNE S166C
value. The register parameter is the VDC register number 165E CMP #$28 ;Was statement token less than 40?
(0-36) and the value parameter is the value (0-255) to be 1660 BCS $1678
stored in that register. The function, RAD, converts an angle 1662 LDY #$50 ;Use table entry at $1650 to list
value from degrees to radians, the system used in BASIC func- 1664 LDA #$16
tions. The format for the function is KAD(angle), where angle 1666 STY $24
1668 STA $25
is the angle value in degrees. Since this is a function, it must 166A BCC $1678
be used on the right side of an operation, as in A = RAD(45). 166C CMP #$0C ;Was function token less than 12?
;Redirect ICRNCH2 vector to $1629 to 166E BCS $1678
1600 LDA #$29
1602 STA $030C ; tokenize new keywords 1670 LDY #$56 ;Use table entry at $1656 to list
1605 LDA #$16 1672 LDA #$16
1607 STA $030D 1674 STY $24
160A LDA #$5A ;Redirect IQPLOP2 vector to $165A to 1676 STA $25
160C STA S030E ; list new keywords 1678 JMP S51CD ;Return to IQPLOP routine
160F LDA #$16 ; Handle execution of statement
1611 STA $030F 167B CMP #$28 ;Was statement token less than 40?
1614 LDA #$7B ;Redirect IGONE2 vector to $167B to 167D BCS $1685
1616 STA $0310 ; handle new statement 167F LDA #$16 ;Put address of execution routine - 1 on stack
1619 LDA #$16 1681 PHA ; (execution routine is at $1866)
161C STA $0311 1682 LDA #$87
161E LDA #$A2 ;Redirect ESC_FN vector to $16A2 to 1684 PHA
1620 STA $02FC ; handle new (unction 1685 JMP $4BA9
1623 LDA #$16 ; STORE routine
1625 STA $02FD 1688 JSR $8803 ;Evaluate register number and value parameters
1628 RTS 168B TXA ;Move value lo accumulator
;Tokenize new keywords 168C LDY $17 ;High byte of register number should be zero
1629 STA $02 .Stash current character 168E BNE $169D
162B LDY #$50 ;Search for keyword in table at $1650 1690 LDX $16 ;Low byte (in X) should be less than 37
162D LDA #$16 1692 CPX #$25
1694 BCS $169D
162F JSR 543E2
1632 BCC $163A ;If no match found, try other table 1696 STY $FF00 ;Set for bank 15 so VDC chip is visible
1634 ADC #$A6 ;Convert index (with bit 7 set) to token (39/$27) 1699 JSR $CDCC;Use screen editor routine
1636 LDX #$00 ;Set flag for extended statement token 169C RTS
1638 BEQ $1647 169D LDX #$0E ;Illegal quantity error if incorrect value supplied
.Search for keyword in table at $1656 169F JMP ($0300)
163A LDY #$56
163C LDA #$16 ;RAD routine
163E JSR $43E2 16A2 CMP #$0C ;Was token less than 12?
1641 BCC $164A ;Exit if no match found 16A4 BCS $16B4
1643 ADC #$8A .Convert index (with bit 7 set) to token (11/$OB) 16A6 JSR $7956 ;Check that parameter ended with a closing
1645 LDX #$FF ;Set flag for extended function token parenthesis
16A9 LDA #$B5 ;Load value from $16B5 into FAC2
198 199
$4006 16390
200 201
16393 $4009 $43B0 17328
202 203
17356 $43CC $4609 17929
208 209
19590 $4C86 $528F 21135
27228 S6A5C
Calculates color fill values 29028 $7164 COLLISION
Handles the COLLISION statement
27257 $6A79 SCNCLR This routine sets up the conditions for COLLISION checking.
Handles the SCNCLR statement The actual testing for collisions occurs during the BASIC IRQ
routine [$A84D].
27482 $6B5A GRAPHIC
Handles the GRAPHIC statement 29072 $7190 SPRCOLOR
Handles the SPRCOLOR statement
27593 $6BC9 BANK
Handles the BANK statement 29110 $71B6 WIDTH
Handles the WIDTH statement
27607 $6BD7 SLEEP
Handles the SLEEP statement 29125 $71C5 VOL
Handles the VOL statement
27693 $6C2D WAIT
Handles the WAIT statement 29164 $71EC SOUND
Handles the SOUND statement
27727 $6C4F SPRITE
Handles the SPRITE statement 29388 $72CC WINDOW
Handles the WINDOW statement
27846 $6CC6 MOVSPR
Handles the MOVSPR statement 29493 $7335 BOOT
Handles the BOOT statement
28129 $6DE1 PLAY If a filename is provided, the routine does the equivalent of
Handles the PLAY statement BLOAD followed by SYS, rather than actually attempting to
This routine has many suboutines to handle parsing and exe- boot a disk.
cution of the strings of music data. PLAY is actually a mini-
language within BASIC. 29554 $7372 SPRDEF
Handles the SPRDEF statement
28631 $6FD7 TEMPO
Handles the TEMPO statement ^ P ^ V 6 3 1 1 7 a : ! t a t e m e n t ; j t ' s a b ^ - i n machine lan-
guage sprite-design utility program.
28644 S6FE4
30444 $76EC SPRSAV
Data tables for PLAY string processing
Handles the SFRSAV statement
28689 $7011
30643 $77B3 FAST
Default values for ENVELOPE instrument tables
Handles the FAST statement
28742 $7046 FILTER
30660 $77C4 SLOW
Handles the FILTER statement
Handles the SLOW statement
28865 $7OC1 ENVELOPE
Handles the ENVELOPE statement
30679 $77D7
Evaluates an expression with a test for type mismatch
216
217
30703 $77EF $837C 33660
224 225
37080 S90D8 $9520 38176
value in the Y register and accumulator (low byte in Y, high 44818 $AF12 JFSUB
byte in the accumulator) into a floating-point value in FAC1.
Entry point for the FSUB routine, currently at 34862/S882E.
44806 $AF06 JFOUT This routine subtracts the floating-point value in FAC1 from
the five-byte floating-point value from the address in bank 1
Entry point for the FOUT routine, currently at 36418/$8E42. specified in the accumulator (low byte) and Y register (high
This routine creates a string of characters representing the byte). (The bank 1 value will be loaded into FAC2.) The result
floating-point value in FAC1. The string starts at location will be left in FAC1.
253/$0100 and is terminated with a zero byte. The first char-
acter of the string is a space (code 32/$20) if the value was 44821 $AF15
positive, or a minus sign ( —) if the value was negative. JFSUBT
Entry point for the FSUBT routine, currently at 34865/$8831.
44809 $AF09 JVAL_1 This routine subtracts the value in FAC1 from the value in
FAC2. The result will be left in FAC1.
Entry point for the VAL_1 routine, currently at 32850/$8052.
This routine reads a string of characters from bank 1 and gen- 44824 $AF18 JFADD
erates the equivalent floating-point value in FAC1. Locations Entry point for the FADD routine, currently at 34885/S8845.
36-37/$24-$25 point to the the starting address of the string This routine adds the floating-point value in FAC1 to the five-
and the accumulator holds the length of the string. This rou- byte floating-point value from the address in bank 1 specified
tine will leave the system in BASIC'S alternate bank 14 con- in the accumulator {low byte) and Y register (high byte). (The
figuration in which block 1 RAM is visible, so it shouldn't be bank 1 value will be loaded into FAC2.) The result will be left
called by a routine in bank 0. in FAC1.
44812 $ AFOC JGETADR 44827 $AF1B JFADDT
Entry point for the GETADR routine, currently at 34837/ Entry point for the FADDT routine, currently at 34888/$8848.
$8815. This routine converts the current value in FAC1 into a This routine adds the value in FAC1 to the value in FAC2.
two-byte unsigned integer in locations 22-23/$16-$17 (low The result will be left in FAC1,
byte in 22/$ 16, high byte in 23/$17). The integer value will
also be in the Y register (low byte) and accumulator (high 44830 $AF1E JFMULT
byte) upon return. Before performing the conversion, the rou-
tine checks that the value FAC1 is in the range 0-65535, and Entry point for the FMULT routine, currently at 35364/$8A24.
generates an ILLEGAL QUANTITY error message if it is not. This routine multiplies the floating-point value in FAC1 by the
five-byte floating-point value from the address in bank 1 spec-
44815 $AF0F JFLOATC ified in the accumulator (low byte) and Y register (high byte),
(The bank 1 value will be loaded into FAC2.) The result will
Entry point for the FLOATC routine, currently at 35957/ be left in FAC1.
$8C75. This routine converts the two-byte unsigned integer in
locations 100-101/$64-$65 (low byte in 101/$65, high byte 44833 $AF21 JFMULTT
in 100/$64) into a floating-point value in FAC1. For this rou-
tine to function properly, you must also load the X register Entry point for the FMULTT routine, currently at 35367/
with the value 144/$90 and make sure the status register $8A27. This routine multiplies the value in FAC1 by the value
carry bit is set. in FAC2. The result will be left in FAC1.
232 233
44836 $AF24 $AF48 44872
44836 $AF24 FDIV the five-byte floating-point value from bank 1 beginning at the
Entry point for the FDIV routine, currently at 35657/$8B49. address specified in the accumulator and Y register (low byte
This routine divides the five-byte floating-point value from the in the accumulator, high byte in the Y register). The exponent
address in bank 1 specified in the accumulator (low byte) and value will be loaded into FAC1. The result of the operation
Y register (high byte) by the floating-point value in FAC1. will be left in FAC1.
(The bank 1 value will be loaded into FAC2.) The result will
be left in FAC1. 44857 $AF39 JFPWRT
Entry point for the FPWRT routine, currently at 368O1/$8FC1.
44839 $AF27 JFDIVT This routine raises the value in FAC2 to the power specified in
Entry point for the FDIVT routine, currently at 35660/$8B4C. FAC1, effectively FAC2 t FAC1. The result of the operation
This routine divides the value in FAC2 by the value in FAC1. will be left in FAC1.
The result will be left in FAC1.
44860 $AF3C JEXP
44842 $AF2A JLOG Entry point for the EXP routine, currently at 36915/$9033.
Entry point for the LOG routine, currently at 35274/$89CA. This routine calculates the natural exponential of the value in
This routine calculates the natural logarithm of the value cur- FAC1, effectively e T FAC1, where e = 2.71828. This is the in-
rently in FAC1, the log to the base e. The result will be left in verse of the LOG operation. The result will be left in FAC1.
FAC1.
44863 $AF3F JCOS
44845 $AF2D JINT Entry point for the COS routine, currently at 37897/$9409.
Entry point for the INT routine, currently at 36091/$8CFB. This routine calculates the cosine of the current value in
This routine calculates the whole number portion of the cur- FAC1, which will be interpreted as an angle in radians. The
rent value of FAC1, removing any fractional portion. The frac- result will be left in FAC1.
tional portion is simply truncated; no rounding is performed.
The result is a floating-point value in FAC1, not an integer 44866 $AF42 JSIN
value. Entry point for the SIN routine, currently at 37904/$9410.
This routine calculates the sine of the current value in FAC1,
44848 $AF30 JSQR which will be interpreted as an angle in radians. The result
Entry point for the SQR routine, currently at 36791/S8FB7. will be left in FAC1.
This routine calculates the square root of the current value in
FAC1. The result will be left in FAC1. 44869 $AF45 JTAN
Entry point for the TAN routine, currently at 37977/$9459.
44851 $AF33 JNEGOP This routine calculates the tangent of the current value in
Entry point for the NEGOP routine, currently at 36858/ FAC1, which will be interpreted as an angle in radians. The
$8FFA. This routine switches the sign of the current value in result will be left in FAC1.
FAC1, making the value negative if it was positive, or positive
if it was negative. 44872 $AF48 JATN
Entry point for the ATN routine, currently at 38067/$94B3.
44854 $AF36 JFPWR This routine calculates the inverse tangent (arctangent) of the
Entry point for the FPWR routine, currently at 36798/$8FBE. current value in FAC1. The result, which can be interpreted as
This routine raises the value in FAC2 to the power specified in an angle in radians, will be left in FAC1.
234 235
44875 $AF4B $AF69 44905
4487S $AF4B JROUND according to the setting of the status register N and Z bits
Entry point for the ROUND routine, currently at 35911/ upon entry. The resulting value will be left in FAC1. If the N
bit is set upon entry, the value in FAC1 will be used as the
$8C47. This routine will round the least significant bit of seed, producing a predictable result. If the Z bit is set, the
FAC1 according to the value in the FAC1 rounding byte, loca- value in the CIA. #1 time-of-day clock is used as a seed. Other-
tion 113/S71. wise, the previous random number in locations 4635-4639/
$121B-$121F is used as a seed for the next value.
44878 $AF4E JABS
Entry point for the ABS routine, currently at 35972/$8C84. 44890 $AF5A JCONUPK
This routine will calculate the absolute value of the current Entry point for the CONUPK routine, currently at 35508/
value in FAC1, making the value positive regardless of its pre- $8AB4. This routine loads FAC2 with the five-byte value at
vious sign. the address in bank 1 pointed to by the accumulator and Y
register (low byte/high byte).
44881 SAF51 JSIGN
Entry point for the SIGN routine, currently at 35927/$8C57. 44893 $AF5D JROMUPK
This routine sets the accumulator (and processor status regis- Entry point for the ROMUPK routine, currently at 35465/
ter) according to the current value in FAC1. If the value is $8A89. This routine loads FAC2 with the five-byte value at
zero, the accumulator will hold 0/$00 upon return (and the the address in the current bank pointed to by the accumulator
status register Z bit will be set). If the FAC1 value is positive, and Y register (low byte/high byte).
the accumulator will hold l/$01 (and the status register Z and
N bits will both be clear). If the FAC1 value is negative, the 44896 $AF60 JMOVFRM
accumulator will hold 255/$FF (and the status register N bit
will be set). Entry point for the MOVFRM routine, currently at 31365/
$7A85. This routine loads FAC2 with the five-byte value at
44884 $AF54 JFCOMP the address pointed to by locations 36-37/$24-$25.
Entry point for the FCOMP routine, currently at 35975/ 44899 $AF63 JMOVFM
$8C87, This routine compares the floating-point value in
FAC1 against the five-byte floating-point value from the ad- Entry point for the MOVFM routine, currently at 35796/
dress in bank 1 specified in the accumulator (low byte) and Y $8BD4. This routine loads FAC1 with the five-byte value at
the address in the current bank pointed to by the accumulator
register (high byte). The accumulator (and processor status and Y register (low byte/high byte).
register) will be set according to the result of the comparison.
If the two values are equal, the accumulator will hold 0/$00
upon return (and the status register Z bit will be set). If the 44902 $AF66 JMOVMF
FAC1 value is greater than the value in bank 1, the accumu- Entry point for the MOVMF routine, currently at 35840/
lator will hold l/$01 (and the status register Z and N bits will $8C00. This routine copies the contents of FAC1 into a five-
both be clear). If the FAC1 value is less than the value in bank byte area beginning at the address in the current bank pointed
1, the accumulator will hold 255/$FF (and the status register to by the X and Y registers (low byte/high byte).
N bit will be set).
44905 $AF69 JMOVFA
44887 $AF57 JRND-0 Entry point for the MOVFA routine, currently at 35880/
Entry point for the RND_0 routine, currently at 33857/$8437. $8C28. This routine copies the contents of FAC2 into FAC1.
This routine generates a pseudorandom floating-point value
236
44908 $AF6C
$AF99 44953
240
Machine Language
Monitor ROM
The duplicate use of the word monitor in computer terminology
may be confusing at first. The term can refer to either hard-
ware, a dedicated video screen used to display information
from the computer, or software, a program used to examine
and modify the contents of memory. Once you understand the
difference, the meaning of monitor is usually obvious from the
context. This chapter describes the 128's built-in software moni-
tor, which resides in the 4K block of ROM from 45056-49151/
$B000-$BFFF. In addition to examining and changing memory,
this monitor allows you to assemble, disassemble, and execute
ML routines; examine and change microprocessor register con-
tents; and copy, compare, save, load, and verify blocks of
memory.
Like the 128's BASIC, its machine language monitor has a
long heritage from previous Commodore models. All of the
original CBM models (except for very early PETs) included a
rudimentary monitor in ROM which allowed users to examine
and modify memory and registers, execute ML programs, and
load and save data, but had no provision for assembling or
disassembling machine language.
The VIC-20 and Commodore 64 had no monitor in built-
in ROM, but sophisticated monitors for both were available on
cartridge. A number of public-domain RAM-resident monitors
were also available, most notably Superman and Micromon. Fi-
nally, the Plus/4 and 16 once again included a monitor pro-
gram in ROM, a version called Tedmon.
The 128's monitor shares many characteristics with all of
its predecessors, but it includes a number of enhancements as
well. One of the most notable is that it allows the entry of
numbers in decimal, octal, or binary in addition to hexadeci-
mal. Whenever the monitor expects a number, you can use a
decimal value if it's prefixed with a + character, or a binary
number if it's prefixed with a % character (in the rare case
when you might want to use an octal—base 8—number, pre-
243
fix it with an ampersand, &). If no prefix is used, then hexa- dresses can span banks—T ED000 EDFFF 1C000, for example.
decimal is assumed. (Hex can also be explicitly specified by Thus, the monitor can effectively see the 16 separate banks as
using a $ character as a prefix.) a single 1024K (16 * 64K) block of memory. One exception is
the F (fill memory) command, which cannot cross bank bound-
Moving Between BASIC and the Monitor aries, because doing so would overwrite the vital contents of
In general, the monitor is aloof from the rest of the 128 ROM locations $00 and $01.
routines. Unlike BASIC—which in a number of places by- The fact that the monitor can see the 128's memory as a
passes the Kernal jump table and calls Kemal routines di- continuous block has an important consequence for the H
rectly—the monitor calls all the Kernal routines it uses (hunt for byte pattern) command. Remember that the banks
through their formal jump table entries. Neither BASIC nor are not really 16 separate blocks of memory, but rather 16 dif-
the Kernal calls any monitor routines other than through jump ferent arrangements of the available RAM and ROM. The low-
table entries. The monitor does not make use of any BASIC est IK of memory (including the input buffer at 512/$0200) is
ROM routines or data tables and for the most part does not in- common to all banks, and at least the lower 4K of block 0
terfere with memory locations used by BASIC. Thus, you may RAM {including the buffer at 2688/$0A80, where the search
pass freely back and forth between the monitor and BASIC pattern is stored) appears in all even-numbered banks and in
without fear of upsetting the BASIC program currently in banks 13/$D and 15/$F.
memory. This greatly enhances the monitor's function as a de- Thus, if you search any bank from beginning to end (for
bugging tool. example, H 10000 1FFFF 'C-128), you'll always find at least
One notable—and highly unfortunate—exception to this one match for your search pattern—in the input buffer at
independence from BASIC is that the monitor uses addresses $0200, where the search command is stored. If you search any
in the range 96-104/$60-$68 as working pointers in most op- even-numbered bank from beginning to end, you'll find at
erations. This area includes the addresses used by BASIC for least two matches for your search pattern—once in the input
its floating-point accumulator 1 (FAC1), where the results of buffer at $0200 and again in the search buffer at $0A80. And
mathematical operations are stored. As a result, it is impossi- if you search all banks from beginning to end (for example, H
ble to use the 128's monitor to directly examine or change the 00000 FFFFF 'COMPUTE!), then you'll always find at least 26
contents of FAC1. This severely limits the usefulness of the matches because of all the times the memory areas used by
monitor for experimenting with BASIC floating-point routines. the input buffer and search buffer appear in the different
One other overlap between BASIC and the monitor is that banks. It's important to choose your address range carefully
the two share the same input buffer area for accepting and when searching for a byte pattern.
processing commands (512-673/$0200-$02Al). Thus, it is not A final note on banks and the monitor: If no bank is ex-
possible to use the monitor to examine the BASIC input buffer plicitly specified, bank 0 is assumed. This is different from
contents or to manipulate data in the input buffer, since the BASIC, which retains the setting specified in a previous BANK
buffer will be at least partially overwritten by the monitor statement, starting with a default of bank 15. So when using
command to display or change the memory area. the monitor, you must always explicitly specify the bank if
you wish to use any bank other than bank 0, It is particularly
Memory Management important to remember this when using the G and J com-
Another particularly attractive feature of the 128's monitor is mands, lest you send the processor off to some uncharted re-
the ease with which it interfaces with the computer's memory gion of memory.
management system. Addresses in monitor commands are For the programmer wishing to make use of ROM
specified as five-digit hexadecimal values, where the first digit routines, those in the monitor are generally less useful than
refers to the bank and the remaining four specify the address those in the BASIC, screen editor, and Kernal portions of the
within the bank. Monitor commands that accept a range of ad- ROM. The monitor JMPs rather than JSRs to the routines used
244 245
45056 $B000 $B08B 45195
to perform monitor commands, so most major routines end by lowing the IMON jump. See IMON for information on how
jumping directly back to the monitor's main loop rather than the indirect vector can be used to wedge in additional monitor
with an RTS opcode. You probably wouldn't want to incorpo- commands.
rate calls to such routines in your own programs because the
routines never return from the monitor. However, the main
command execution routines use a number of subroutines that 45065 $B009 MONBRK
do end with RTS opcodes, and you may find some of these Monitor entry routine when BRK instruction encountered.
useful, particularly the routines to convert and print byte val- Prints BREAK and a {BELL} character, then retrieves and
ues as decimal numbers (at 47623/$BA07 and 47687/SBA47) stores the bank number, program counter, and microprocessor
or as hexadecimal numbers (at 47250/$B892). An example is register values that were placed on the stack by the IRQ/BRK
provided at the end of the chapter. handling routine [$FF17], then branches into the following
routine to fall through to the register display and main loop.
commands consist of a single character). With this character in from the stack, it adds 1 to the address value before placing
the accumulator, the routine jumps through the IMON indirect the value in the 8502's program counter. The actual execution
vector at 814-815/$032E-$032F. Normally, this vector points addresses for each of the commands handled by this table are
to the jump table entry at $B006, which immediately returns as follows:
to the address following the indirect jump. However, this vec-
tor can be changed to allow additional commands to be added A {Assemble instruction) SB406
C (Compare memory blocks) SB231
to the monitor. See the discussion at IMON for more details.
D {Disassemble instruction) $B599
The routine then compares the command character in the F {Fill memory) SB3DB
accumulator against characters from the command table at G (Go to routine) $B1D6
45286/$B0E6. If no match is found, an error is assumed, and H (Hunt for byte) $B2CE
(at $B0BC) the error signal (a question mark) is printed follow- J (Jump to subroutine) $B1DF
ing the command. The routine then loops back to process an- M (Memory display) $B152
other command. If a match is found among the first 15 char- R (Register display) $B050
acters in the command table, then the command is executed T (Transfer memorv) $B234
by pushing an address from the table at 45308/$B0FC onto X (eXit to BASIC) $B0E3
the stack, then jumping to read the parameter following the @ (send disk command) $BA90
command. The RTS at the end of the parameter decoding rou- (same as A) $B406
tine [$B7A7] will cause control to be passed to the command > (change memory) $B1AB
execution address stored on the stack. If the matching charac- (change register) $B193
ter is among characters 16-19 in the table ($-%), then a jump
is taken to the base conversion routine [$B9B1]. If the match- 45338 SB11A MINDFET
ing character is among characters 20-22 in the table (L-V), INDFET call for the monitor.
then a jump is taken to the routine that prepares for load,
save, or verify [$B337]. Calls the Kernal INDFET routine [$FF74] to retrieve a charac-
ter into the accumulator from the bank specified in 104/$68 at
the address pointed to in 102-103/$66-$67, and with the off-
45283 SB0E3 EXITMON set specified by the contents of the Y register. The use of
Handles X {exit to BASIC) command. $66-$68 as working addresses makes it impossible to use the
Leaves the monitor and returns to BASIC by jumping indi- monitor to examine the contents of floating-point accumulator
rectly through BASIC'S restart vector at 2560-2561/ 1 (FAC1), since the value in FAC1 will be changed by the
$0A00-$0A01. monitor M command (which uses this routine).
45286 $B0E6 COMTBL 45354 $B12A MINDSTA
Table of monitor commands. INDSTA call for the monitor-
Each of the 22 commands consists of a single character: Calls the Kernal INDSTA routine [$FF77] to store the value in
the accumulator into the bank specified in 104/$68 at the ad-
A C D F G H J M R T X @ . > ; $ + & % L S V
dress pointed to in 102-103/$66-$67, and with the offset
45308 $B0FC EXECTBL specified in the Y register. The use of $66-$68 as working ad-
Table of execution addresses for the monitor commands. dresses makes it impossible to use the monitor to load values
Each two-byte entry in the table consists of the address minus directly into floating-point accumulator 1 (FAC1), since the
1 of the routine to perform the corresponding command. The value in FAC1 will be changed by the > (memory change)
entries are one less than the actual address because of the way command (which uses this routine).
the RTS opcode behaves: When RTS pulls a return address
248
J 249
45373 $B13D 8B1AB 45483
250 251
45526 3B1D6 $B231 45617
must work from the starting address toward the ending ad- tine [$FFE1], so the RUN/STOP key can be used to be used to
dress, while upward moves must work from end to start. Oth- terminate the search. The routine ends by jumping back to the
erwise, if the source and destination ranges overlap, a single main loop [$B08B],
value would be rippled through the destination range. Be sure to see the warning in the introduction to this
The routine loads bytes from the source address range chapter about using the H command for searching wide ad-
and, if a transfer operation is indicated, stores the value in the dress ranges.
corresponding destination address using the Kernal INDSTA
routine [$FF77]. Next, it compares the byte in the source range 45879 $B337 MONLSV
against the byte in the destination range using the Kernal Prepares for load, save, or verify.
INDCMP routine [$FF7A]. This performs the compare opera- Begins by setting default values for the device number, sec-
tion (the bytes should always be equal for a transfer opera- ondary address, bank, filename length, and filename address.
tion). If the bytes do not match, the address of the mismatch is Setting these values directly (rather than using Kernal routines
printed. Then the source and destination addresses are either like SETLFS, SETNAM, and SETBANK) is an exception to the
incremented (for a compare or downward transfer) or decre- monitor's otherwise strict use of Kernal jump table calls. If no
mented (for an upward transfer). This loop is repeated until all characters follow the command, then a branch to 45995/$B3AB
bytes in the range have been compared or transferred; then allows the L and V commands to be used alone to load or ver-
the routine jumps back to the main loop [$B08B], However, ify using "nameless" tape files.
the loop also includes a call to the Kernal STOP routine If anything follows the command, it is assumed to be a
[$FFE1], so the RUN/STOP key can be used to halt the com- filename and must start with a quotation mark character ("),
pare or transfer. or else an error will be signaled. Characters following the
opening quotation mark are copied into the monitor buffer at
45774 $B2CE SEARCH 2688/$0A80 until a closing quotation mark is found. An error
Searches memory for byte pattern. is signaled if no closing quotation mark is found or if more
Evaluates the address parameters and calculates the number of than 16 characters are used in the filename. If no other param-
bytes to search, then fills the buffer at $0A80 with the search eters are found following the closing quotation mark, a branch
pattern. If the first nonspace character following the ending to 45995/$B3AB attempts to load or verify a tape file with the
address parameter is the apostrophe ('), then the following specified name.
characters are copied directly from the input buffer into the If a parameter value follows the closing quotation mark,
search buffer, so the search will be for the actual ASCII char- the low byte of the value is copied into the device number lo-
acters. If the apostrophe is not found, the characters following cation (186/$BA). The next parameter value is assumed to be
the ending address are converted into byte values before being a starting address, A load or verify is attempted if the param-
placed in the buffer. eter is absent. The final parameter, if any, is assumed to be the
ending address. If it's missing, a branch to 46O33/$B3D1 at-
Once the search buffer is prepared, a byte is loaded from
tempts a relocating load or verify. If it is present, the com-
memory and compared against the first byte in the search
mand is checked, and an error is signaled if it is not S (an
buffer. If the two bytes match, the next byte in memory is
ending address cannot be specified for a load or verify).
compared to the next byte in the buffer, and so on, until either
a mismatch occurs or the end of the search buffer is reached
(which indicates that the pattern has been matched). In the 45983 $B39F MONSAVE
case of a match, the starting address of the match is printed, Handles save for monitor.
followed by two spaces. The testing process normally repeats Changes the secondary address setting to zero to specify a re-
until all bytes in the specified address range have been locatable file if the device is the tape drive. The Kernal SAVE
checked, but the loop includes a call to the Kemal STOP rou-
254 255
45995 SB3AB $B406 46086
routine [$FFD8] is used to write the data to the specified de- bytes in the specified addresses. Overwriting either of these
vice. The routine ends by jumping back to the main loop areas will likely result in a system lockup.
[SB08B].
46086 $B406 ASSMBLE
45995 $B3AB MONLOAD Handles A (assemble) command or its equivalent (.).
Handles load and verify. Checks for values following the A or period (.) and signals an
Checks that the command is either V or L, and signals an er- error if none is found. The period is accepted as a synonym
ror if not. For V, the character code for V (86/$56) is left in for A to simplify the assembly process by allowing you to edit
the accumulator; for L, a zero is placed in the accumulator. the lines displayed by the D (disassemble) command. Since
The Kernal LOAD routine [$FFD5] is then called, which will the D command automatically provides the period before each
perform a load if the accumulator holds zero (for L) or a verify line, you may not have realized that it is treated as a separate
if the accumulator holds a nonzero value {for V). The routine command, but you can substitute it freely for A.
tests for a verify error; if one occurs, the message ERROR is If only an address is found following the command, the
printed to signal that the data in memory does not match the routine simply returns to the main loop [$B08B], Next, the
file on disk or tape. The routine ends by jumping back to the routine searches for the first group of three nonspace charac-
main loop [$B08B], ters. Any values on the input line with fewer than three char-
acters are ignored;this explains why the two-digit hexadecimal
46033 6B3D1 byte values displayed in front of the three-character mnemonic
Prepares for relocating load or verify. by the disassemble routine are ignored when the instruction is
Loads the specified ending address value and changes the sec- edited. It also explains why changes to the two-digit byte val-
ondary address (185/$B9) from 1 to 0, indicating a relocating ues are ignored by this routine. The three-character pattern is
load is to be attempted. The routine then branches to attempt then packed into a two-byte value. This packing scheme is a
load or verify [$B3AB], holdover from the RAM-resident monitors of earlier Commo-
dore computers. It's really unnecessary in the 128, which has
46043 $B3DB FILLMEM room to spare in this block of memory, but Commodore's pro-
grammers probably found it easier to reuse the existing code.
Fills memory with specified byte value.
All 8502 ML mnemonics consist of combinations of the alpha-
Evaluates the starting and ending addresses, and calculates the betic characters A-Z. Since there are only 26 different valid
number of bytes to fill. If the starting and ending banks are characters, any single character can be represented by a five-
not the same, an error is signaled to prevent the fill operation bit value (which can hold 0-31), and three five-bit values can
from crossing bank boundaries and overwriting the important fit nicely into two eight-bit bytes.
values in locations $00 and $01. If the address range is valid,
the fill byte value is read, and a loop begins to store fill byte As an example of how this packing works, suppose the
in all memory locations in the specified range. The loop nor- pattern found is LDA—corresponding to hex bytes $4C $44
mally repeats until the specified number of bytes have been $41. First, the value 63/$3F is subtracted from each byte,
filled, but it includes a call to the Kernal STOP routine yielding $0D $05 $02. The binary equivalents are %00001101
[$FFE1], so the RUN/STOP key can be used to halt the fill. %00000101 %00000010. The rightmost five bits of each value
are shifted rightward into two bytes. The resulting packed
The routine ends by jumping back to the main loop [$B08B].
mnemonic in these locations is %01101001 %0l000100, or
When filling, you must be careful not to overwrite page 0
$69 $44.
or page 2, both in the area of memory common to all banks.
Page 0 contains the pointer to the byte to fill (102-104/$66- Next, the routine infers an addressing mode from the pa-
$68), and page 2 contains the INDSTA routine used to store rameter following the three-character pattern. The packed pat-
tern is compared against those in the table at 46881/$B721.
256 257
46489 8B599 $B707 46855
(The packing scheme does make the testing for valid mne- monies column. A call to 46753/SB6A1 unpacks and prints
monics slightly faster, since only two bytes need to be com- the mnemonic. The associated parameter value is then printed,
pared instead of three.) An error is signaled if no match is along with such characters as #, (, and ), to identify the ad-
found; otherwise, the position of the matching mnemonic in dressing mode for the instruction. For relative branching in-
the table is used along with the addressing mode to calculate structions, the target address of the branch is printed instead
the proper opcode for the specified instruction. The opcode of the relative offset value.
and its associated parameter (if any) are then stored in mem-
ory, and the routine at 46556/$B5DC is called to disassemble 46681 $B659 CALCMN
the line just assembled. This provides the hex values of the
Calculates mnemonic and addressing mode.
ML bytes. Finally, the routine loads the input buffer with an A
and the next address value so that these will be found when Manipulates the specified opcode (in the accumulator upon
the routine ends by jumping back to the main loop [$B08B], entry) to provide the offset into the table for the correspond-
This greatly simplifies the assembly of further instructions. ing packed mnemonic, an addressing mode identifier value,
and a count of associated data bytes (0-2).
46489 8B599 DISASSM 46753 $B6A1 PRNTMN
Handles D (disassemble) command. Prints mnemonic for opcode.
Calculates the number of bytes to disassemble, then calls Unpacks and prints a mnemonic from the table at 46881/$B721.
46548/$B5D4 as many times as necessary to disassemble that Upon entry, the accumulator holds the offset into the table for
many bytes. If no parameter is specified, 20 bytes are dis- the mnemonic to be printed. As an example of how the un-
assembled beginning at the address in 102-104/$66-$68. (Ac- packing works, the first table entry is $1C $D8. The binary
tually, up to 22 bytes may be disassembled, depending on equivalent is %0001110011011000. Divided into three five-bit
how many are necessary for the last full instruction.) If no pre- groups (and ignoring the rightmost bit), that's %00011 %10011
vious commands have been executed, the address value is un- %01100, or $03 $13 $0C. Adding $3F to each yields $42 $52
predictable. After an earlier D command, the value will be the $4B, corresponding to the character codes for the letters BRK.
next address beyond the last one previously disassembled. If You would expect this to be the first table entry, since the BRK
only a starting address is provided, 20 bytes are disassembled instruction has the lowest possible opcode ($00).
beginning at the specified address. If both starting and ending
address parameters are provided, all instructions between 46787 $B6C3 OPCDTBL
those addresses will be disassembled. However, the disassem-
Opcode decoding table.
bly loop includes a call to the Kernal STOP routine [$FFE1], so
the RUN/STOP key can be used to halt the disassembly. You The values in this table are used by the mnemonic and mode
may also use the NO SCROLL key to pause the disassembly. calculation routine [$B659] to determine the packed mnemonic
The routine ends by jumping back to the main loop [$B08B], table offset for the specified opcode value.
260 261
47314 8B8D2 8B983 47491
if the ending address is less than the starting address, the and with 8/$08 (maximum number of digits) in the accumu-
carry status bit will be set upon exit to signal the error. lator and 3/$03 (number of bits-per-digit minus 1) in the Y
register.
47537 $B9B1 NUMXVRT
Performs number base conversion. 47760 8BA90 DISKCMD
Evaluates the parameter following the base symbol, then Handles @ (disk) commands.
prints the value of the number in four different number bases: Checks whether a parameter was found following the com-
hexadecimal, decimal, octal, and binary. The routine can con- mand. If so, the low byte of the value specifies the device
vert values in the range 0-1,048,575. For the hex value, a dol- number for the disk command. If no parameter is specified, a
lar sign is printed followed by four hex digits (five if the value device number of 8—the most common number for disk
is greater than 65535/$FFFF). For decimal, octal, and binary, drives—is used. If the first nonspace character following the
this routine provides the leading character (+ for decimal, & device number is a dollar sign, then the routine branches to
for octal, and % for binary), then uses the subroutine at 47875/$BB03 to display a disk directory. Any other characters
47687/$BA47 to display the values. The routine ends by following the device number parameter are sent over the serial
jumping back to the main loop " device as a command to the specified device. The routine ends
by jumping back to the main loop [$B08B],
47623 SBA07 HEXDEC Because the first item following the @ is always inter-
Converts a hexadecimal value to decimal. preted as a device number, you must specify some device
Converts the three-byte hexadecimal value in 96-98/$60-$62 number value (@8 10 is a valid command, but @I0 isn't be-
into a decimal value in BCD (binary coded decimal) format in cause the 10 will be interpreted as an invalid device number).
2720-2723/$0AA0-$0AA3. For example, converting the value However, an alternate syntax is possible. The parameter eval-
258/$102, stored in 96-98/$60-$62 as $02 $01 $00, will result uation routine [$B7A7] exits when it encounters a comma, so a
in $00 $00 $02 $58 being left in 2720-2723/ $0AA0-$0AA3. comma can be used alone to specify a null parameter. Thus, a
This routine takes advantage of the 8502's rarely used decimal command of the form @,I0 is acceptable—the default device
mode. To prevent the complications that would likely be number (8) will be used.
caused by interrupts occurring while the processor is set for
decimal mode, interrupts are disabled until the 8502 is reset to 47875 $BB03 SHOWDIR
its normal (binary) mode. Displays disk directory.
If the first nonspace character in the command string following
47687 $BA47 PNTOBD the @ command is a dollar sign, this routine is branched to
Prints octal, binary, or decimal values. because a disk directory requires more elaborate screen for-
Prints the octal or binary equivalent of a three-byte value. En- matting than the simple disk status messages otherwise re-
ter with 96-98/$60-$62 holding the three-byte value, the ac- turned by the @ command. This routine is a good model for a
cumulator holding the maximum number of digits allowed directory display using machine language. (You can't use this
(8/$08 for octal, 24/$18 for binary), and the Y register hold- routine directly because it ends with a branch that returns to
ing the number of bits to interpret per printed digit minus 1 the monitor main loop [$B08B].)
(2/$02 for octal, 0/$00 for binary). To print a decimal value,
enter at 47709/$BA5D with the decimal value in 2720-2723/ 47986-49151 $BB7 2 -$BFFF Unused
$OAA0-$OAA3 in BCD format (see the routine 47623/$BA07), The final 1166 bytes in the monitor ROM block are unused and
contain 255/SFF (except the last two bytes, which are $00 $3A).
264 265
Programming Example
The following program, which prints a countdown in both
decimal and hexadecimal, illustrates how several of the moni-
tor routines can be incorporated into your own ML programs.
Use the command J $F0B00 to execute the routine:
0B00 LDA #$10 ;Load $60-$62 w i t h t h e
0B02 STA $60 ; initial count
0B04 LDA #$27
0B06 STA $61 ; $002710 (10,000 decimal)
0808 LDA #$00 ; in this example
0B0A STA $62
0B0C JSR $B8B4 ;Clear a line for the display
OBOF JSR $B8AD ;Move print position to clear line
0B12 JSR $BA07 ;Convert byte value to decimal
0B15 LDA #$00 ;Set up for decimal p r i n t i n g
0B17 LDX #$08
0B19 LDY #$03
0B1B JSR $BA5D ;Print decimal value
0B1E JSR $B8A8 ;Print a space
0B21 JSR $B901 ;Transfer value to working storage
0B24 JSR $B892 ;Print hexadecimal value
0B27 JSR $B922 ;Decrement count v a l u e
0B2A BCS $0B0F ;Loop until value reaches zero
0B2C RTS
266
Screen Editor ROM
If the 128 is your first computer, or if you have upgraded to
the 128 from an earlier Commodore model, then you may not
appreciate the power and versatility of the 128's full-screen
editor. The editor is so well integrated into the system that
you may take it for granted. However, if you've ever worked
with an Apple, Radio Shack, TI-99, or other computer with
limited editing features, you'll appreciate the ability to move
the cursor to any position on the screen, insert and delete
characters, and reenter entire lines just by pressing RETURN
anywhere on the line. (Imagine the frustration of having to re-
type an entire line of input just because a single character was
mistyped.) And, with the addition of ESC key sequences, the
128's screen editor is even more powerful and versatile than
the earlier Commodore editors from which it is descended.
In earlier Commodore models, the screen editing routines
were an integral part of the Kernal ROM, but in the 128 the
routines have been separated and moved to their own block of
ROM, occupying locations 49152-53247/$C000-$CFFF. The
routines in this block handle keyboard input and all aspects of
text screen output for both the 40- and 80-column displays.
Special features such as bitmapped graphics and sprites are
handled in BASIC ROM, but editor routines set up the bit-
mapped and multicolor bitmapped screens.
The 40- and 80-column text displays constitute the main
output device for the 128, and thereby its primary mechanism
for communicating with the user. For the fundamentals of
how each display is generated, refer to the description of the
respective 40- and 80-column video chips in Chapter 8. Note
that both video sources remain on at all times, so it's possible
to connect both a composite and an RGBI or monochrome
monitor and have simultaneous 40- and 80-column displays.
At any given time, however, one of the screens will be consid-
ered active and the other inactive, That is, the cursor will
"live" on only one of the displays, and all printing will be di-
rected to that screen. The active screen is considered device 3,
the default output device for the system.
269
Windows tains a four-byte line link bitmap at 862-865/ $035E-$0361.
One of the most significant new features of the 128's screen
output is that it's window-oriented. That is, printing and Each screen line has a corresponding bit in the map. A bit set
cursor movement are confined to the boundaries of a win- to %1 indicates that the corresponding line is linked to the
dow—a defined area of the screen—rather than to the abso- one above. See the entries for location 862/$035E and for the
lute height and width of the screen. The window can be, and routines at 52084-52144/$CB74-$CBB0 for more information.
most often is, the full size of the screen, but it can be as small The 128 also implements a tab feature using a similar bit-
as a single character. Once you change the window bound- mapping scheme. The ten bytes at 852-861/$0354-$035D
aries, you must think in terms of windows rather than screens. provide a bit corresponding to each screen column, A bit in
For example, you should think of the SHIFT-CLR/HOME key the map set to %1 corresponds to a tab stop. See the entry for
as "clear window" rather than "clear screen." Only the cur- location 852/$0354 and for the routines at 51535-51597/
rently defined window area will be cleared when that key $C94F-$C98D for more information.
combination is pressed. You can also limit printing to certain The other major function of the screen editor is to handle
areas of the screen by modifying the window margins. The input from the keyboard. Although you tend to think of the
128's windowing capabilities are no match for those of more keyboard as an integral part of the computer, the system sees
advanced computers like the Macintosh and Amiga, but they it as just another peripheral, device 0. The keyboard is the de-
do offer exceptional control over display formatting. fault input device for the 128. It is normally scanned during
In order to understand how characters in the window are the jiffy IRQ sequence. See the entry for the SCNKEY routine
manipulated, you must first understand the distinction between [$C55D] for details. The system's two major Kernal input
physical lines and logical lines. A physical line is just one hor- routines, GETIN [$EEEB] and BASIN [$EF06], both call screen
izontal row of the window—the characters between the left editor routines to retrieve input from the keyboard.
and right margins. However, when you print characters on the An enhanced feature of the 128's keyboard is programma-
screen and the printing overflows from one row into the next, ble keys. Definition strings can be assigned to the eight func-
the editor will consider the physical lines to be linked together tion keys, F1-F8, and to the SHIFT-RUN/STOP combination
into a single logical line. Lines will continue to be linked until and the HELP key. The definitions can be of variable lengths,
either the RETURN or SHIFT-RETURN characters are encoun- with the restriction that the combined lengths of all ten defini-
tered. A logical line can be as short as a single physical line or tions cannot exceed 246 characters.
as long as the entire window, depending on how many char- The screen editor has another feature that makes redefin-
acters are printed before the RETURN or SHIFT-RETURN. (By ing the keyboard much easier than on previous Commodore
contrast, the Commodore 64 allows logical lines to span a models. The tables for decoding keyscan codes into character
maximum of two physical lines.) Some screen editor routines codes are still in ROM, but the pointers to the tables are now
operate on physical lines, others on logical lines. The entries maintained in RAM. Thus, redefining the keyboard is as sim-
in this chapter indicate when an operation affects an entire ple as redirecting the pointer to a new decoding table set up in
logical line. RAM. See the entry for locations 830-841/$033E-$0349 for
details.
Line Links
The system for linking lines on the 128 is considerably differ- Screen Editor Jump Table
ent from that of earlier Commodore models. For example, the Most major screen editor routines can, and should, be entered
Commodore 64 maintains a table at 217-242/$D9-$F2 which through their respective entries in the following jump table.
contains the high bytes of the first address on each screen line, Each three-byte table entry consists of a JMP opcode followed
with the high bit of each address byte used to indicate whether by the address of the target routine.
the line is linked. The 128 has no such table; instead, it con-
270
271
49152 3C00F 49167
$cooo
49152 $cooo JCINT RETURN character, the value 13/$0D. If the flag is zero, the
Entry point for the routine at 49275/$C07B/ which establishes routine accepts characters from the keyboard and displays
the default characteristics for both the 40- and 80-column dis- them on the screen until RETURN is pressed. It then returns
plays. This entry is part of both the reset and RUN/STOP- the first character of the input in the accumulator and sets the
RESTORE sequences. No preliminary setup is required, but source flag to a nonzero value so that subsequent calls retrieve
the behavior of the routine is affected by the setting of the ini- characters from the input line displayed on the screen. In
tialization status flag (2564/$0A04). The keyboard decoding either case, the source flag should be set only before the first
table pointers and screen editor indirect vectors are initialized call to this routine for any given line of input.
only when bit 6 of the flag is %0. If you wish to preserve de- For keyboard input, the starting and ending columns and
coding table pointers or indirect vectors while resetting other the row for the input line are set automatically. For screen in-
screen editor characteristics, set this bit to %1 before you call put, the character is read from the row specified in 235/$EB at
the routine. the column specified in 236/$EC. These locations normally
hold the current cursor position and are advanced one position
to the right after each call to this routine. However, the loca-
49155 $C003 JDISPLY tions can also be reset to any row and column you desire. The
Entry point for the routine at 52276/SCC34, which deposits a screen input line ends on the row specified in 2608/$0A30 at
screen code and attribute value at the current cursor position. the column specified in 234/$EA. Neither of these locations is
Call this entry with the accumulator holding the screen code set automatically, so you must specify the ending position
(not the character code) for the desired character and the X before calling for input from the screen. The X and Y register
register holding the attribute value for the character. contents will be preserved during this routine.
49158 SC006 JKEYIN 49164 $C00C JPRINT
Entry point for the routine at 49716/SC234, which retrieves a Entry point for the routine at 50989/$C72D, which prints a
single character from the keyboard. (In official Commodore lit- character at the current cursor position using the current
erature, this routine has the rather nondescriptive name LP2.) attribute (in 241/$F1). This routine is used by the Kernal
This entry is used by the Kernal GETIN routine [SEEEB] when BSOUT routine [$EF79] when the screen is specified as the
the keyboard is the input device. (The keyboard, device 0, is output device. (The screen, device 3, is the 128's default out-
the 128's default input device.) Upon return, the accumulator put device.) Call the entry with the accumulator containing the
will contain the retrieved character. Be sure to see the warning character code (not the screen code) for the character to be dis-
in the KEYIN entry about calling this routine directly. played. The accumulator and X and Y register contents are
preserved during this routine.
49161 C009 JGETSCRN
Entry point for the routine at 49819/$C29B, which retrieves a 49167 $C00F JSCRORG
character from a line of keyboard or screen input. (In official Entry point for the routine at 52315/$CC5B, which returns
Commodore literature, this routine has the rather nondescrip- information about the current window size. This entry is the
tive name LOOP5.) This entry is used by the Kernal BASIN target of the Kernal jump table entry JSCRORG [$FFED], Upon
routine [$EF06] when input is requested from the keyboard return, the X register will hold the number of columns (minus
(device 0) or the screen (device 3). The input source is deter- 1) in the current window, and the Y register will hold the
mined by the value in the flag at 214/SD6. When the flag has number of rows (minus 1). The accumulator will hold the
a nonzero value, the character at the current cursor position is maximum column number for the active screen (39 for the 40-
read and returned in the accumulator. When the end of the column display or 79 for the 80-column display).
line of input is reached, the routine returns the code for the
272 273
49170 $C012 $C02A 49194
274 275
49197 8C02D 8C07B 49275
276 277
49275 $C07B SC15E 49502
2607/$0A2F 8/$08 Base page for attribute memory in 8563 49474 SC142 CLEAR
RAM (attributes begin at 2048/$0800) Clears the current window and homes the cursor.
2612/$0A34 208/$DO Default raster line for split screen (text por- Also handles clear screen character, CHR$(147).
tion starts at line 20)
2619/$0A3B 4/$04 Base page for 40-column screen memory Sets the cursor to the home position and clears rows until the
(value read from 49228/$C04C) bottom of the window is reached, then falls through into the
following routines to return the cursor to the home position
Also during this setup, the active screen flag (215/$D7) is and set pointers.
set for 40-column mode, and bit 7 of the MMU mode configu-
ration register (54533/$D505) is set to %1 to enable reading of
the 40/80 DISPLAY key. While the 40-column display is ac- 49488 $C15O HOME
tive, default tab stops are set and default screen editor vari- Moves the cursor to the home position of the current window.
ables are copied from the table at 52852/$CE74 into 224-249/ Sets the cursor row (235/$EB) and starting row for input
$E0-$F9. At the same time, default variables for the 80-col- (232/$E8) to the top row of the current window (229/$E5),
umn display are copied from the table at 52878/$CE8E into and the cursor column (236/SEC) and starting column for in-
2624-2649/$0A40-$0A59. However, there is a bug in this put (233/$E9) to the left margin of the current window
portion of the routine: The copy loop uses an index of 26/$lA (230/$E6), then falls through into the next routine to set
instead of the proper value 25/$19, so the byte following the pointers to that line.
40-column table is also copied to 250/$FA, and the byte fol-
lowing the 80-column table is also copied to 2650/$0A5A. 49500 $C15C SETLINE
The screen editor indirect vectors (820-829/$0334-$033D) are Sets starting address pointers for the current line.
initialized from the table at 49253/$C065. Loads the line number where the cursor currently resides
Next, bit 6 of the initialization status flag (2564/$0A04) is (235/$EB) into the X register, then falls through into the next
checked. If the bit is set to % 1 , the following steps to load routine to set pointers to that line.
keyboard table pointers and key definition strings are skipped.
If the bit is clear, the keyboard decoding table pointers 49502 $C15E SETADDR
(830-841/$033E-$0349) are initialized from the table at Sets starting address pointers for a specified line.
4926/$C06F, and the default programmable key definitions Calculates the screen memory address corresponding to the
are copied to the definition area at 4096/$1000 from the table leftmost column of the screen line specified in the X register
at 52904/$CEA8. After the values are copied, bit 6 of the flag and places the address in the pointer at 224-225/$EO-$E1.
is set to %1 to indicate that these steps have been performed. The low byte of the address comes from the table at 49203/
The flag is cleared before this routine is called by the reset $C033 (multiplied by 2 if the 80-column display is active). The
routine [$EOO0], so these steps will always be performed dur- high byte is calculated by taking a value from the table at
ing a reset. However, the RUN/STOP-RESTORE sequence 49228/$C04C, masking off all but the lowest two bits (and
[$FA53] does not affect the flag, so any changes to pro- multiplying the result by 2 if the 80-column screen is active),
grammable key definitions or keyboard decoding table point- then ORing the result with the starring page value for the ac-
ers will remain intact after RUN/STOP-RESTORE. tive screen—2619/$0A3B for the 40-column display or
Default tab stops are then established for the 80-column 2606/$0A2E for the 80-column display.
screen, and the 80-column window is reset to full screen size Next {at 49532/$C17C), the attribute memory address
and cleared. The 40-column window is also reset to full screen corresponding to the leftmost column of the specified screen
size and cleared. Finally, the position of the 40/80 DISPLAY line is calculated and placed in the pointer at 226-227/
key is read (by checking bit 7 of 54533/$D505), and the se- $E2-$E3. The low byte of the address is taken directly from
lected display will become the active screen upon exit. the low byte of the screen memory pointer (224/$E0). For the
278 279
49556 $C194
SC234 49716
maining characters is decremented and the offset into the defi- pointers to the input screen line and jumps to 49852/$C2BC
nition area is incremented; then the routine exits with the in the following routine to exit with the accumulator holding
character in the accumulator, the status register carry bit clear, the first character of the input—unless no other characters
and IRQ interrupts reenabled. were typed before RETURN, in which case the routine
If no programmable key string characters are pending, the branches to 49829/$C2A5 in the following routine to exit with
character at location 842/$034A, the first character in the key- the RETURN character code in the accumulator.
board buffer, is returned in the accumulator. Any remaining
characters in the buffer are shifted one position to the left to 49819 8C29B GETSCRN
remove the retrieved character from the buffer; then the count Performs BASIN from screen or keyboard.
of characters in the buffer (208/$D0) is decremented. Upon (This routine has a jump table entry at 49161/$C009.)
exit, the status register carry bit will be clear and IRQ inter-
Stashes the contents of the X and Y registers on the stack for
rupts will be reenabled.
later restoration, then checks the input source flag (214/$D6).
Unlike other major screen editor routines with jump table If the flag value is zero, indicating input from the keyboard,
entries, you should avoid calling this one directly. To retrieve the preceding routine is used to accept a line of input from the
keypresses, call the Kernal GETIN routine via its jump table keyboard. If the flag is nonzero, but with bit 7 clear (%0), the
entry (65508/$FFE4) with the current input device (153/$99) routine branches ahead to 49852/$C2BC to retrieve a charac-
set to zero to indicate keyboard input. The Kernal GETIN rou- ter from a screen line. If bit 7 is set (%1), the end of the input
tine [$EEEB] verifies that a character is waiting to be read from line has been reached, so (at 49829/$C2A5) the input source
either a programmable key string or the keyboard buffer flag is reset to zero and a RETURN character is printed unless
before it calls this routine. If you call this routine with no output is to a device other than the screen. The routine then
characters available (with 208/$D0 and 2O9/$D1 both con- exits with the RETURN character code, 13/$0D, in the accu-
taining zero), you'll cause serious problems. The contents of mulator (the X and Y registers will be restored to their original
all page 3 locations above the keyboard buffer (and part of 40-
column screen memory in page 4) will be garbled. This area values).
includes the vital indirect fetch and store routines; you'll have At 49852/$C2BC, the screen code at the current cursor
to reset the computer to recover. position is retrieved and converted into the corresponding
character code (disassemble $C2C2-$C2D8 to see the conver-
49752 8C258 KEYLIN sion process). The routine then checks whether the end of in-
Accepts a line of keyboard input and returns the first character. put has been reached. If so, bit 7 of the input flag is set to %1
(The normal entry point for this routine is 49755/$C25B.) to indicate that all characters have been read from the current
input line.
Turns on the cursor, then waits until a character is available in
the keyboard buffer or from a programmable key definition The cursor is then moved right to the next character posi-
string. The routine above is called to retrieve the character, tion in the line. If the calculated character code is 222/$DE,
and unless it's a RETURN character, code 13/$0D, the routine the pi (K) character, it's replaced with 255/$FF, an alternative
loops to display the character on the screen at the current value (and BASIC token) for that character. Before exiting, the
cursor position (using the PRINT routine [$C72D]), move the original X and Y register values placed on the stack at the start
cursor to the next position, and wait for another character to of the routine are restored, and retrieved character code is
become available. When RETURN is encountered, the routine loaded into the accumulator. The status register carry bit will
falls out of this loop and stores the RETURN code in the input be clear upon exit.
source flag (214/$D6) so that subsequent calls to the keyboard Although there are no bugs in this routine, its calling
BASIN routine will retrieve characters from the line of input Kernal routine (BASIN [$EF06]) will not correctly retrieve a
that has been displayed on the screen. The routine then sets line of input from the screen (keyboard input functions prop-
erly). The screen input setup portion of BASIN has two major
282 283
49919 8C2FF SC320 49952
flaws: It does not set the ending row for input (2608/$0A30), and X and Y registers with the values stored on the stack
and it resets the input source flag (214/$D6) before each char- when the BSOUT routine was entered [$C72D], so all register
acter is retrieved (so that the setting of bit 7 is lost). Together, values are preserved during BSOUT. The status register carry
these bugs make it impossible to determine when the end of bit will be clear upon exit.
the input is reached. The following is an example of the Because the address of this routine is pushed onto the
proper technique for retrieving a line of input from the screen: stack at the start of the screen BSOUT routine [$C72D], all
LDA $EB ;Set ending row for input screen printing subroutines will return to the calling routine
STA $0A30 ; (same as starting row) via this routine.
LDA $E7 ;Set ending column for input
STA $EA ; (to right window margin) 49952 $C320 SETCHAR
LDA #$03 ;Set screen as input source Handles character printing for screen BSOUT.
STA $D6 ; (any nonzero value will do) Handles all character display functions for the screen BSOUT
LDX #$00 ;Initialize storage offset routine [$C72D], including quote, reverse, and autoinsert
LOOP JSR $C009 ;Read character from the screen modes. The routine has several entry points, depending on the
CMP #$0D ;Is it RETURN?
BEQ EXIT ;Exit if so desired effect. For any of these entry points, the code to be
STA $0C00,X ;Stash character from screen printed should be in the accumulator upon entry:
INX increment the offset 49952/$C320: Entry point for printing character codes
BNE LOOP ;Loop for another character 160-254/$A0-$FE. Prior to entry, bit 7 of the code will have
EXIT RTS been cleared to %0. This step forces bit 6 to % 1 , so character
codes 160-191/$A0-$BF become screen codes 96-127/
49919 $C2FF QUOTECK $60-$7F, and character codes 192-254/$C0-$FE become
Handles quote mode flag. screen codes 64-126/$40-$7F.
Checks whether character value in the accumulator is 34/$22, 49954/$C322: Entry point for printing character codes
the quote (") character. If so, bit 1 of the quote mode flag 3 2-12 7/$ 20-$ 7F. Prior to entry, the character code will have
(244/$F4) is toggled, turning quote mode on if it was previ- been converted to a screen code by the screen BSOUT control
ously off or off if it was previously on. The character value routine [$C72D]. This step checks whether reverse mode is ac-
will still be in the accumulator upon exit. tive (indicated by a nonzero value in 243/$F3). If that mode is
not active, the next step is skipped.
49932 $C30C PRNTEXIT 49958/$C326: Entry point for printing characters in reverse
Provides common exit for screen BSOUT subroutines. video; also used for character codes less than 32 and for codes
128-159 when those characters are printed in quote mode or
Stores the current character code (239/SEF) as the previous
at a pending insert. For codes 1-31/$O1-$1F, the character
character code (240/SFO). The subroutine to move the cursor
code is used unchanged, so those characters are represented
on the 80-column screen [$CD57] is called to actually move
by the reverse images of screen codes 1-31/$O1-$1F. For char-
the cursor if that display is active. This is necessary because
acters 128-159/$80-$9F, bit 7 will have been cleared to %0,
the 80-column screen's cursor is controlled by hardware (not
and bit 6 set to %1 prior to entry, so those characters are rep-
by software, like the 40-column screen's cursor), so it doesn't
resented by the reverse images of screen codes 64-95/$40-$5F.
automatically move when its corresponding row and column
If autoinsert mode is active (indicated by bit 7 of 246/$F6
pointers are updated. The pending insert count (245/$F5) is
set to %1), a space is inserted at the current cursor position
checked. If it's nonzero, the quote mode flag is cleared. As a
before the character is printed. (The count of inserts pending is
result, you won't go into quote mode if you type the quote
also cleared; you can't have inserts pending in autoinsert
character for a pending insert unless the quote is typed for the
mode.) The subroutine at 52271/$CC2F is used to place the
last insert. Before exiting, the routine reloads the accumulator
284 285
49982 8C33E SC445 50341
286 287
50492 6C53C SC55D 50525
line number and the Y register will hold the column number the key at row 0 of column 0 (INST/DEL), to 87, for the key
of the right window margin. at row 7 of column 10 (NO SCROLL).
Several keys on the 128 keyboard are not included in the
50492 $C53C keyscan matrix. The CAPS LOCK key (read at bit 6 of location
Fills or copies a block of 8563 RAM. l/$01) is tested at the start of this routine. The 40/80 DIS-
Uses the hardware fill/copy feature of the 8563 chip to fill or PLAY key (read at bit 7 of location 54533/$D505) is tested
copy a block of the 8563's private 16K of RAM. The block during the screen initialization routine [$C07B]. The SHIFT
starts at the address currently in 8563 registers 18-19/$12-$13 LOCK key is a switch that has the effect of holding down the
and ends at the address in 2620-262 l/$0A3C-$0A3D. The op- left SHIFT key. The RESTORE key isn't read at all; it's con-
eration is determined by the state of bit 7 of 8563 register nected to circuitry which generates an NMI interrupt signal to
24/$18. If the bit is %0, the block is filled with the value in the processor when the key is pressed (see the NMI handling
8563 register 31/$1F. If the bit is % 1 , the contents of locations routine [$FA40]).
starting at the address in registers 32-33/$20-$21 are copied If the key at the intersection of the row and the column
to the block. being tested is pressed, the row bit will be %0; otherwise, it
will be % 1 . If a key is found to be pressed, the character code
50525 $C55D SCNKEY for the key is read from the default decode table. Unless the
Scans keyboard matrix for keypress. character code read from the table is 8, 4, 2, or 1, the keyscan
(This routine has a screen editor jump table entry at 49170/SC012 code (not the character code) for the key is stored in 212/$D4,
and a Kernal jump table entry at 65439/$FF9F.) and the routine goes on to scan the next position. However, if
Begins by checking bit 6 of location l/$01 to determine the the character code has one of these values, that value is ORed
position of the CAPS LOCK key. If that key is down, the shift with the shift key flag to set a bit in the flag value.
key flag (211/$D3) will be set to 16/$10 (bit 4 set to %1); Note that it's the keyboard decode table, not the physical
otherwise, it will be cleared to zero. Next, the keyscan code keyboard layout, that determines which keys are treated as
(212/$D4) is initialized to 88/$58, the value for no key shift keys. In the default ROM keyboard decode table at
pressed. The keyboard matrix is checked to see whether any 64128/$FA80, the ALT key (keyscan code 80) decodes as
keys are pressed. If not, the routine jumps to 50839/$C697 in character code 8, the CONTROL key position (keyscan code
the next routine to set 88 as the matrix code value. If a key 58) holds character code 4, the Commodore logo key position
has been pressed, the routine loads the keyboard decode table (keyscan code 61) holds character code 2, and the left and
pointer (204-205/$CC-$CD) from 830-831/$033E-$033F, right SHIFT key positions (keyscan codes 15 and 52, respec-
which holds the address of the default table, and begins the tively) both hold character code 1. Thus, pressing either SHIFT
process of determining which key is being pressed. key normally sets bit 0 of 211/$D3 to % 1 , and the Commo-
The keyboard is arranged electrically as a matrix of 11 dore, CONTROL, and ALT keys set bits 1, 2, and 3, respec-
columns and eight rows (Figure 7-1). To scan for a keypress, tively. (You can change this by modifying the default
the CIA or VIC port bit for one of the 11 columns is set to %0, keyboard table. See the entry at 830-831/$033E-$033F for
while the bits for all other columns are held at % 1 . While the more information.) Since the matrix code isn't stored when
column bit is %0, the CIA port for the eight rows (56321/ these shift keys are processed, 212/$D4 will never contain 15,
$DC01) is read, and, one by one, the bits corresponding to the 52, 58, 61, or 80 while the standard decode table is being
rows are tested. The count of scanned keys is incremented used. So the SHIFT, ALT, Commodore, and CONTROL keys
after each row bit is tested, so each key in the matrix has a can't normally be detected by checking 212/&D4. Their states
keyscan code corresponding to the number of keys scanned must be determined from 211/$D3.
when that key's position is tested. The codes range from 0, for
288 289
50525 $C55D $C55D 50525
290 291
50769 8C651 50769
SC651
match is found, the count of pending programmable key string 50919 6C6E7 CRSR40
characters (2O9/$D1) is loaded with the length of the cor- Handles cursor blinking for 40-column screen.
responding definition string from the table at 4096-4105/ Begins by checking the active screen flag (215/$D7), exiting
$1000-$ 1009, and the offset into the definition area at immediately if the 80-column display is active. The routine
4106/$ 100A for the string is calculated and stored in also exits if the cursor blink switch (2599/$0A27) holds a non-
210/$D2. (A simple way to defeat this feature and make the zero value. Then, the cursor blink countdown value (2600/
function keys simply generate character codes as they do in $0A28) is decremented. The countdown is necessary because
the Commodore 64 is to change the KEYCHJC vector to point the cursor can't be blinked during every interrupt—that would
to 50871/$C6B7 so that this portion of the routine is skipped,) result in blinking too fast to see. If the cursor countdown
If the character isn't one of the programmable keys, the doesn't reach zero, the routine exits. If the count does reach
number of characters currently in the keyboard buffer (208/ zero, the cursor flag (2598/$0A26) is tested. If that flag indi-
$D0) is compared against the maximum number the buffer can cates that the solid cursor is selected and the cursor is re-
hold (2592/$0A20). If the buffer is full, the current keypress is versed, the routine exits (the solid cursor just stays reversed).
ignored. Otherwise, the character code is stored in the next Otherwise, it's time to switch the cursor's phase.
available position in the buffer at 842-851/$034A-$0353. The first step in switching phases is to reset the count-
From there, it can be retrieved by the Kernal GETIN and BA- down to its starting value—20/$14. That value will result in
SIN routines. the cursor changing phase every 20/60 second. Because it
Before exiting, the value 127/$7F is stored in the CIA I/O takes two phase changes (on-to-off and off-to-on) to blink the
port register for keyboard columns. This value (%01111111) cursor, the cursor blinks every 40/60, or 2/3, second. Since
sets the line for column 7 of the matrix low, while all other this value is part of this ROM routine, it's not possible to
lines are high, so that the keys in that column can be detected change the cursor blink rate while using the standard screen
by reading the row register (56321/$DC01). This feature is IRQ routine.
provided to allow testing for the RUN/STOP and Commodore If the cursor is currently in its reversed phase, the position
keys, but other keys on that row can also be detected outside is restored to its original color and screen code. If the cursor is
the normal keyscan. See the routine at 63037/$F63D and the in its normal phase, the screen code and color for the position
entry for location 145/$91 for more information. are stashed (in 2601/$0A29 and 2602/$0A2A, respectively).
Then the high bit of the screen code is toggled, and the re-
50909 $C6DD PFKCHRS versed screen code is written back to the current cursor posi-
Table of programmable key character values. tion using the current cursor color (in 241/$F1). Finally, the
This table is used to identify programmable keys and to deter- cursor phase bit (bit 6) in the cursor flag (2598/$0A26) is
mine the offset into the definition length table at 4096/$1000 toggled.
for the length of the corresponding string. This routine is part of the normal IRQ sequence. There is
Offset Character Code Key no corresponding routine to blink the cursor on the 80-column
0 133/$85 Fl screen because the 8563 80-column chip handles that opera-
1 137/$89 F2 tion automatically.
2 134/$86 F3
3 138/S8A F4 50989 8C72D PRINT
4 135/$87 F5 Handles BSOUT to the screen.
5 139/$8B F6 (This routine has a jump table entry at 49164/$C00C.)
6 136/$88 F7
7 140/$8C F8 Begins by storing the current character code (in the accumu-
131/$83 SHIFT-KUN/STOP lator upon entry) in 239/$EF. The current accumulator and X
9 132/$84 HELP and Y register values are then stashed on the stack for restora-
tion upon exit.
294
50989 8C72D 3C78C 51084
The next portion of the routine implements the pause is called to handle the quote (") character. Then the routine
printing feature. If the pause flag (2593/$0A21) contains a jumps to 49954/$C322 to display the calculated screen code at
nonzero value, the routine immediately loops to check the flag the current cursor position using the current attribute (241/$F1).
again. It remains in the flag testing loop until the flag value is Remember that the address pushed onto the stack causes
reset to zero. If you're wondering how the routine ever breaks the final printing or character handling subroutine called by
out of this loop, remember that normal processing is sus- this routine to return to 49932/$C30C. That routine restores
pended during interrupts. The flag value is set during the IRQ- the accumulator and X and Y registers from the stack, so they
driven SCNKEY routine. This means that if you ever call contain the same values upon exit that they did upon entry.
BSOUT while interrupts are disabled, you must be sure that
the pause flag contains a zero. Otherwise, the flag value will 51055 8C76F RTRN
never change, and the routine will be stuck in the loop until Handles RETURN and SHIFT-RETURN characters, CHR$<13> and
you reset the computer. It also means that, as long as the nor- CHR$(141).
mal IRQ is enabled, NO SCROLL and CONTROL-S can be Finds the position of the last nonspace character in the logical
used to pause screen printing in any program that calls line; then clears the link bit for the physical line just below
BSOUT—even in your own machine language programs. Re- that position, making the line following the current logical line
member, however, that since the pause loop is implemented the start of a new logical line. The cursor position is set to the
only in this routine, NO SCROLL and CONTROL-S can halt left margin of that line, and the screen line pointers are up-
printing to the screen only. dated to reflect the new cursor position. The routine then falls
Next, the input source flag (214/$D6) is reset to zero, through into the following one.
making the keyboard the input source. The value 49931/
$C30B is pushed onto the stack. This will cause the RTS at the 51069 $C77D MODESOFF
end of the printing subroutine—or at the end of the special Cancels quote and reverse modes and clears pending inserts
handling subroutine in the case of screen and color control (ESC-O and ESC-ESC).
characters—to jump to 49932/$C30C, the common exit rou- Bits 4 and 5 of the current attribute value (241/$F1) are cleared,
tine for all screen BSOUT subroutines. canceling flashing or underlined modes for subsequent charac-
If the code to be printed is 13/$0D (RETURN) or 141/ ters on the 80-column display. The pending insert (245/$F5),
$8D (SHIFT-RETURN), a branch is taken to 51055/$C76F to reverse mode (243/$F3), and quote mode (244/$F4) flags are
handle these special cases. Otherwise, 240/$F0 is checked to all reset to zero, canceling any pending inserts and turning off
see whether the last character printed is the ESC (escape) reverse and quote modes.
character, 27/$lB. If so, the code is the second character of an
ESC sequence, so a jump is taken to the ESC sequence han- 51084 $C78C
dler at 51646/$C9BE. Character codes greater than 127/$7F Tables of screen control codes and dispatch addresses.
are sent to a special handling routine at 51202/SC802, and Locations 51084-51097/$C78C-$C799 comprise a table of all
codes less than 32/$20 are sent to 51126/$C7B6. the character codes less than 32 which have a special function
Remaining characters, those with codes in the range (except for RETURN and ESC, codes 13 and 27, which are de-
32-127/$20-$7F, are converted to screen codes as follows: If tected in the main screen BSOUT routine [$C72D]). The sub-
the code is less than 96/$60, bit 6 is cleared. Character codes routine to handle codes less than 32 [$C7B6] compares the
32-63/$20-$3F are unchanged, becoming screen codes 32-63/ current character against these values. If a match is found, the
$20-$3F, while character codes 64-95/$40-$5F become screen corresponding dispatch address from the table at 51098-51125/
codes 0-31/$00-$1R If the code is 96 or greater, only bit 5 is $C79A-$C7B5 is placed on the stack to be called by the next
cleared, so character codes 96-127/$60-$7F become screen RTS. Because of the way the RTS opcode behaves, adding 1 to
codes 64-95/$40-$5F. Next, the subroutine at 49919/$C2FF the address placed on the stack, the address table values are 1
296 297
51126 SC7B6 $C802 51202
less than the actual address of the target routine. The table If quote mode is active, the routine clears the character
shows the characters handled and the actual addresses of the storage location (239/$EF) and branches to 49958/SC326 in
handling routines: the character printing routine to display the character code
Handling
Character Handling (0-31) as a screen code in reverse mode. If quote mode is not
Offset Code Routine Description active, the accumulator contents are compared against the 14
0 2/$02 51399/$C8C7 Turns on underline mode control character codes in the table at 51084/$C78C. If a
1 7/$07 51598/$C9BE Generates bell tone match is found, the dispatch routine [$C7F6] is used to execute
2 9/$09 51535/$C94F Moves cursor to next tab stop the corresponding subroutine. Otherwise, the routine falls
3 10/$0A 51633/$C9B1 Performs linefeed through into the next routine to check whether the character is
4 11/$OB 51366/$C8A6 Disables case switching a color change code.
5 12/$0C 51372/$C8AC Enables case switching
6 14/$0E 51328/$C880 Switches to lowercase set
15/$0F 51413/IC8D5 Turns on flashing mode 51162 $C7DA COLORSET
7
8 17/$11 51290/$C85A Moves cursor down one line Handles color change characters.
9 18/$12 51394/$C8C2 Turns on reverse mode Compares the character code in the accumulator with the table
10 I9/$13 51379/$C8B3 Moves cursor to home position of color character codes at 52812/$CE4C. If no match is
11 20/$14 51483/$C91B Deletes a character found, the routine exits. If the accumulator value matches a ta-
12 24/$18 51553/$C961 Sets or clears a tab stop ble entry, the X register will contain the table offset for the
13 29/$lD 51284/$C854 Moves cursor right one column match, a value in the range 0-15. For the 40-column display,
this value is placed in the current attribute flag value
51126 6C7B6 (241/SF1). For the 80-column display, the offset value is used
Interprets character codes less than 32. as an index into the table at 52828/$CE5C to retrieve the cor-
Jumps indirectly through the CTLVEC vector (820-821/ responding 8563 color code. That value is then placed in the
$0334-$0335), which is initialized on system reset to point to lower four bits of the attribute flag.
51129/10769, the location immediately following the indirect
jump. However, the vector can be redirected to your own rou- 51190 8C7F6
tine in RAM, allowing you to modify the effects of printing Calls control code execution routines.
any of the characters with codes less than 32. See the entry at Uses the control code index, in the X register upon entry, as
CTLVEC for details. an offset into the dispatch table at 51098/$C79A. The cor-
If the value in the accumulator is the ESC character, responding subroutine address is retrieved from the table and
27/$lB, the routine exits without performing any other check- pushed onto the stack, so the RTS at the end of this routine
ing. Otherwise, the routine checks whether an insert is pend- will transfer control to the subroutine.
ing. If so, the routine branches to handle the character just as
it would if quote mode were active. If no inserts are pending, 51202 SC802
the code is compared with the delete character value 20/$14, Interprets character codes greater than 127.
If the code matches, the routine branches past the following
Jumps indirectly through the SHFVEC vector (822-823/
test for quote mode. Because delete character handling is sand-
$0336-$0337), which is initialized on system reset to point to
wiched between the test for pending inserts and the test for
quote mode, it's possible to type deferred deletes when inserts 51205/$C805, the location immediately following the indirect
are pending, but not during quote mode. Delete is the only jump. However, the vector can be redirected to your own rou-
character singled out for this treatment: All other control char- tine in RAM, allowing you to modify the effects of printing
acters (except RETURN and ESC) are deferred when printed any of the characters with codes greater than 127. See the en-
while quote mode is active. try at SHFVEC for details.
Next, the high bit of the character code (in the accumu-
298 299
51220 $C814 $C875 51317
lator upon entry) is masked off, and the resulting value is If the code is not among this group, bit 7 of the accumulator is
compared against 32. If the value is less, indicating that the reset to %1 to restore the character to its original value. Then
original character code was in the range 128-159, a branch is the routine branches to 51162/SC7DA to test whether this is a
taken to the following routine to handle those characters. Oth- color change character.
erwise, the routine tests whether the result was 127, indicating
that the original code was 255, the pi (rc) character. If not, the 51284 $C854
routine jumps to 49952/$C320 in the character printing rou-
Handles cursor right character, CHR$(29).
tine to display the character corresponding to the specified
code. However, if the code was pi, it's changed to 94/$5E, the Calls the subroutine to move the cursor one position to the
screen code for the pi character, before jumping to the printing right [$CBED], then tests whether the cursor is wrapped to the
routine. left margin of a new line. If so, a branch is taken to the rou-
tine which determines whether the cursor has moved down
onto a new logical line.
51220 $C814
Handles character codes 128-159.
51290 $C85A
Checks whether quote mode is in effect and, if so, sets bit 6 of Handles cursor down character, CHR$(17).
the character value in the accumulator (converting the ad-
Calls the subroutine to move the cursor down one row
justed character code value 0-31 into a screen code value in
[$C363]. Upon return, the routine falls through into the next
the range 64-95), then jumps to 49958/$C326 in the character
routine to see whether the cursor has moved onto a new logi-
printing routine to display the control code as a reverse character.
cal line.
If quote mode is not in effect, the code tests against the
value 20/$14 to determine if it was originally the insert char-
acter— CHR$(148). If so, the routine jumps to 51427/$C8E3 to
51293 $C85D
Checks whether cursor moved onto a new logical line.
handle the insert. Otherwise, the count of pending inserts is
checked. If inserts are pending, the character is treated as if Checks whether the link bit for the current physical line is set
quote mode were in effect—it's converted to a screen code and to % 1 , indicating that the cursor is still on the same logical
printed in reverse video. Performing this test after checking for line. If not, bit 7 of 232/SE8 is set to %1 to indicate that the
the insert character allows multiple insertions to be made. input begins on the first line in a logical chain,
If no insert is pending, the accumulator value is compared
against a series of character values, branching or jumping to 51303 $C867
the appropriate handling routine if a match is found. The table Handles cursor up character, CHR$(145).
shows the address of the routine to which control is trans- Exits without moving if the cursor is already on the top line of
ferred if a match is found. (The table shows the original char- the window. Otherwise, the previous routine is used to deter-
acter code value before the high bit is masked off; the value mine if the cursor has moved onto a new logical line. Then
actually tested for in this routine will be 128 less): the row (235/$EB) is decremented, and screen line pointers
Character Handling are updated to reflect the change.
Code Routine Description
145/$9l 51303/$C867 Moves cursor up one line 51317 $C875
157/$9D 51317/$C875 Moves cursor left one position Handles cursor left character, CHR$(157).
142/$8E 51346/$C892 Switches to uppercase/graphics set Calls the subroutine to move the cursor one position to the
146/$92 51391/$C8BF Turns off reverse mode left [$CC00]. Upon return, the routine exits with the status
130/$82 51406/$C8CE Turns off underlining register carry bit set if the cursor is already at the upper left
143/$8F 51420/$C8DC Turns off flashing characters
147/$93 49474/$C142 Clears the window corner of the window (the cursor will not be moved in this
300 301
51328 $C880 $C8B3 51379
case). Otherwise, the routine exits immediately with carry flag (241/$F1) to %0. This bit, which has no effect on 40-
clear, unless the move wrapped the cursor to the right margin column printing, determines which character set will be used
of the line above. In that case, a test of whether the cursor for any characters subsequently printed on the 80-column
moved onto a new logical line must be performed, and the screen using this attribute value. Characters already on the
cursor row value (235/$EB) and screen line pointers must be screen are not affected, so it's possible to mix character sets on
updated. the 80-column display.
302 303
51391 $C8BF $C93D 51517
306 307
51678 SC9DE $CA1B 51739
Next, the routine checks whether the character code (in ESC E 51979/$CB0B Sets nonblinking cursor mode
the accumulator upon entry) is also ESC. If so, the current ESC F 52001/$CB21 Sets blinking cursor mode
ESC G 52023/$CB37 Enables bell tone for CHR$(7)
character is shifted right one bit. This changes the character ESC H 52026/$CB3A Disables bell tone for CHR$(7)
from 27/$lB to 13/$0D, the RETURN character, so that dual ESC I 51773/$CA3D Inserts a blank screen line
ESCs are not read repeatedly. The routine then jumps to the ESC 52145/$CBB1 Moves cursor to start of logical line
routine to cancel quote mode. This is an undocumented fea- I
ESC K 52050/$CB52 Moves cursor to end of logical line
ture of the ESC sequences: ESC ESC is a handy shortcut for ESC L 51938/ICAE2 Enables screen scrolling
ESC O. ESC M 51941/$CAE5 Disables screen scrolling
If the character is not ESC, bit 7 is masked off. This ESC N 52040/$CB48 Sets normal 80-column screen
means that shifted letters are treated the same as unshifted ESC 0 51069/$C77D Cancels quote mode
ones. ESC SHIFT-A has the same effect as ESC A, for ex- ESC P 51851/$CA8B Erases to start of logical line
ample. (Remember, however, that only the alphabetic letter ESC Q 51830/$CA76 Erases to end of logical line
keys have this relationship. ESC SHIFT-@ is not the same as ESC R 52031/$CB3F Reverses 80-column screen
ESC @.) ESC S 51954/$CAF2 Sets block cursor (80-column)
ESC T 51732/$CA14 Sets top left corner of window
Next, 64/$40 is subtracted from the character values. This ESC U 51966/SCAFE Sets underline cursor (80-column)
will translate the character codes for @ and A-Z into an index ESC V 51900/$CABC Scrolls screen up one line
in the range 0-26. If the result is outside this range, there is ESC 51914/$CACA Scrolls screen down one line
no standard ESC sequence for the specified character, so the ESC
w
X 52524/$CD2C Switches active displays
routine exits without taking further action. If the character is ESC Y 51587/$C983 Sets default tab stops
within the valid range, the address of the subroutine to per- ESC 51584/$C980 Clears all tab stops
form the corresponding sequence is loaded from the table at z
51678/$C9DE. It is pushed onto the stack so that the subrou- 51732 $CA14 SETTOP
tine will be called when the RTS opcode at the end of this
routine is executed. Defines the upper left corner of the window (ESC T>.
Clears the carry bit, then uses a BIT opcode to fall through
into the following routine to load the current cursor position
51678 $C9DE ESCTBL and set the window boundary.
Table of ESC key dispatch addresses.
Each two-byte entry in this table consists of the address minus 51734 $CA16 SETBTM
1 of the subroutine to perform the corresponding ESC key se- Defines the lower right corner of the window (ESC B).
quence. The routine to handle ESC sequences [$C9BE] pushes Sets the carry bit, loads current cursor position, then falls
a table entry on the stack so that the RTS at the routine causes through into the following routine to set the window
a jump to the subroutine. Each entry is one less than the ac- boundary.
tual address because of the way RTS behaves: When RTS
pulls an address from the stack, the address value is incre- 51739 $CA1B WINDOW
mented before being placed in the 8502's program counter. Sets window boundaries.
The actual execution addresses for each of the subroutines are (This routine has a jump table entry at 49197/$C02D.)
as follows: Establishes a window boundary according to the values in the
ESC @ 51871/$CA9F Clears to end of screen accumulator and X register and the setting of the status regis-
ESC A 51949/$CAED Enters autoinsert mode ter carry bit. If entered with carry clear, the accumulator value
ESC B 51734/$CA16 Sets bottom right corner of window defines the new top row of the window, and the X register
ESC C 51946/$CAEA Cancels autoinsert mode
ESC D 51794/$CA52 value defines the new left margin. If entered with carry set,
Deletes an entire logical line
309
308
51748 SCA24 $CACA 51914
the accumulator value defines the new bottom row, and the X row of the next logical line upward to overwrite the current
register value defines the new right margin. The newly de-
fined window is not cleared, but the routine does fall through
t line (blank lines will be added at the bottom of the window).
The cursor is then moved to the left margin of the original top
to the portion of the following routine that clears the line link row of the deleted logical line. Bit 7 of the input starting line
bitmap, so all lines in the window will initially be unlinked. value (232/SE8) is set to % 1 , indicating that the cursor is at
When using this routine, remember that row and column the start of a logical line.
numbering begins with zero (column 0 of row 0 is the upper
left corner of the screen). Thus, SYS 51739,9,19,0,0 would set 51830 $CA76
the upper left corner at the twentieth column over on the Erases to the end of the current logical line (ESC Q).
tenth line down. The routine does not check the validity of Clears to the end of the current row, then checks whether the
your entries; you are responsible for making sure that the next row is linked to the current one. If so, that line is cleared
lower right corner values are at least equal to the upper left as well. This continues until the last row of the logical chain is
corner values. If you set a lower right corner that is above or reached. The cursor is restored to its original position upon
to the left of the upper left corner, the screen display will be exit.
garbled.
51851 $CA8B
51748 $CA24 FULLW Erases to the start of the current logical line (ESC P).
Resets the window to full screen size. Prints a space at the current cursor position, then checks
Sets the bottom right corner of the window to the maximum whether the cursor is at the left margin of the first row in a
row and column settings, held in 237/$ED and 238/SEE, re- logical chain. If not, the cursor is moved left and another
spectively; then sets row 0, column 0 as the upper left corner. space is printed, repeating until the start of the logical line is
Finally, the routine clears all bytes in the line link bitmap, ef- reached. The cursor is then restored to its original position.
fectively unlinking all screen lines.
51871 $CA9F
51773 $CA3D Erases to the end of the window (ESC @).
Inserts a blank line (ESC I). Clears to the right margin of the current row, then moves
Copies all lines in the window starring at the row on which down to the next row and clears the remainder of the window
the cursor currently resides one row lower (the bottom row one logical line at a time until the bottom of the window is
will be lost); then clears the row where the cursor resides and reached. The cursor is then restored to its original position.
moves the cursor to the left margin of the cleared line. The
link bit for the line below the new one (the line that originally 51900 $CABC
occupied the new line's position) is tested. If the link bit is set Scrolls the display up one line (ESC V).
to % 1 , the new line has been inserted within an existing logi- Copies all lines in the window up one row (the top row will
cal line, so the link bit for the new line will also be set to add be lost) and clears the bottom row. The cursor is then restored
it to the logical chain. If the new line is not linked to a previ- to its original position,
ous line, bit 7 of the input starting line value (232/$E8) is set
to %1 to indicate that the cursor is at the start of a logical line. 51914 $CACA
Scrolls the display down one line (ESC W).
51794 $CA52 Copies all lines in the window down one row (the bottom row
Deletes the current logical line (ESC D). will be lost) and clears the top row. The cursor is then restored
Determines which row is the first of the current logical line, to its original position.
then scrolls all lines in the window beginning with the first
310 311
51938 $CAE2 $CB3F 52031
51938 $CAE2 then copies the flag value to the 8563 chip cursor register
Enables screen scrolling (ESC L). (RIO). This causes the cursor to begin on raster line 7 of the
Loads the accumulator with 0/$00, then uses a BIT opcode to screen line, the scan line below the character patterns.
fall through into the following routine and store this value in
the scrolling enable flag (248/$F8). 51979 $CB0B
Disables cursor blinking (ESC E).
51941 $CAE5 Begins by checking which display is currently active. If the 80-
Disables screen scrolling (ESC M). column display is active, bits 5 and 6 of the 80-column cursor
Stores the value 128/$80 in the scrolling enable flag (248/ flag (2603/$0A2B) are cleared to %0. Then the flag value is
$F8), setting bit 7 to % 1 . As long as bit 7 of that flag is set, copied to the 8563 chip cursor register (RIO). This halts the
the printing routines will not scroll new lines onto the win- blinking of the cursor on the 80-column screen. If the 40-
dow, and the cursor will wrap at window margins. column display is active, bit 6 of the 40-column cursor flag
(2598/$0A26) is set to %1 to disable cursor blinking.
51946 $CAEA
Cancels autoinsert mode (ESC C). 52001 $CB21
Loads the accumulator with 0/S00, then uses a BIT opcode to Enables cursor blinking (ESC F).
fall through into the following routine and store this value in Begins by checking which display is currently active. If the 80-
the autoinsert enable flag (246/SF6). column display is active, bits 5 and 6 of the 80-column cursor
flag (2603/$0A2B) are set to % 1 . Then the flag value is copied
51949 SCAED to the 8563 chip cursor register (RIO). This causes the cursor
Enables autoinsert mode (ESC A), on the 80-column screen to blink. If the 40-column display is
Stores the value 128/$80 in the autoinsert enable flag (246/ active, bit 6 of the 40-column cursor flag (2598/$0A26) is
$F6). As long as that flag contains a nonzero value, the print- cleared to %0 to enable cursor blinking.
ing routines will insert a space before each character is
printed. 52023 $CB37
Enables tone for bell character (ESC G).
51954 $CAF2 Loads the accumulator with 0/$00, then uses a BIT opcode to
Changes 80-column cursor to solid block (ESC S). fall through into the following routine and store this value in
Checks the active screen flag, exiting immediately if the 80- the bell disable flag (249/$F9).
column display is not active. If it's active, the routine clears
bits 0-4 of the 80-column cursor flag (2603/$0A2B) to %00000, 52026 8CB3A
then copies the flag value to the 8563 chip cursor register Disables tone for bell character (ESC H).
(RIO). This causes the cursor to begin on raster line 0 of the Stores the value 128/$80 in the bell disable flag (249/$F9),
screen line, making the cursor block the same height as the setting bit 7 to % 1 . As long as bit 7 of that flag is set to % 1 ,
character patterns. no tone will be sounded when character code 7 is printed.
312 313
52040 $CB48 $CBC3 52163
315
52205 8CBED $CC5B 52315
52205 8CBED FORWARD then allow the routine to fall through to 52276/$CC34 to dis-
Moves the cursor one position to the right. play the space.
Checks whether the move would place the cursor beyond the
right margin of the window. If not, the new position value is 52271 $CC2F DISPLY1
set in 236/$EC. If the cursor is already at the right window Displays a character using the current attribute.
margin, the subroutine at 50019/$C363 is called to move the Loads the X register with the current character color from the
cursor to the left margin of the next line, scrolling the window attribute flag (241/SF1), then uses a BIT opcode to allow the
if the cursor is on the bottom line (or wrapping the cursor to routine to fall through to 52276/$CC34 to display the screen
the top of the window if scrolling is not allowed). Upon exit, code in the accumulator.
the carry bit will be set if the move caused the screen to scroll
(or the cursor to wrap). The accumulator contents are pre- 52274 $CC32 DISPLY2
served unchanged during this routine; the cursor column will Displays a character using the previous attribute.
be in the Y register upon exit.
Loads the X register with the current character color from the
previous attribute flag (242/$F2), then falls through to display
52224 $CC00 RETREAT the screen code in the accumulator.
Moves the cursor one position to the left.
Checks whether the move would place the cursor beyond the 52276 $CC34 DISPLY
left margin of the window. If not the new position value is set Displays a character at the current cursor position.
in 236/$EC, and the carry bit is cleared. If the cursor is al- {This routine has a jump table entry at 49155/$C003.)
ready at the left window margin, the routine checks whether Places a character on the screen by putting the screen code
the cursor is on the top row of the window. If so—if the value (in the accumulator) into the screen memory location
cursor is currently in the home position of the window—the corresponding to the current cursor position. The attribute
routine exits with the carry bit set and without moving the value (in the X register) is then stored into the attribute mem-
cursor. Otherwise, the cursor position is set to the right margin ory location corresponding to the current cursor position.
of the screen line above the current one. In this case, the Z bit (Note that the accumulator should contain a screen code, not a
in the status register will be set upon exit. The accumulator
character code.) The screen memory address is determined by
contents are preserved unchanged during this routine; the
using the current cursor column (236/$EC) as an offset from
cursor column will be in the Y register upon exit.
the first screen memory position for the screen line
(224-225/$E0-$El), and the attribute memory address is de-
52254 $CC1E SAVEPOS termined by using the current column value as an offset from
Stores the cursor position for later restoration. the first attribute memory position for the screen line
Stashes the current cursor column value in temporary storage (226-227/$E2-$E3). For the 40-column screen, the screen
at 222/SDE and the current cursor row value at 223/$DF. The code and attribute values are stored directly into the memory
corresponding routine to retrieve these values and restore the locations. For the 80-column screen, the values must be stored
cursor to the saved position is at 51506/$C932. in the 8563 chip's private 16K of RAM indirectly, via the 8563
registers.
52263 $CC27 SPACE
Prints a space. 52315 $CC5B SCRORG
Loads the X register with the current character color from the Returns height and width of current screen window.
attribute flag (241/$F1), masking out bits 4-6, and loads the (This routine has a screen editor jump table entry at 49167/$C00F
accumulator with 32, the screen code for a space. BIT opcodes and a Kernal jump table entry at 65517/$FFED.)
316 317
52330 6CC6A 8CCA2 52386
Calculates the screen height by subtracting the top margin of the screen display. This makes no difference as long as the
(229/$E5) from the bottom margin (228/$E4); this value is re- window is set for full screen size, but it is significant when
turned in the Y register. The screen width is calculated by- you are using a reduced-size window. For example, if the
subtracting the left margin (230/$E6) from the right margin cursor is on the eighth row down from the top of the screen
(231/$E7); this value is returned in the X register. The accu- and the tenth column across from the left edge of the screen,
mulator is loaded with the maximum column number for the the row and column values returned by this routine will be 7
screen in use (238/$EE)—39/$27 for the 40-column screen or and 9, respectively, if the window is full screen size. However,
79/$4F for the 80-column screen. if the top left corner of the window is moved to the sixth col-
Note that the height and width values calculated by this umn of the sixth row, the row and column values returned for
routine will be one less that the actual number of rows and the same cursor position will be 1 and 3, respectively.
columns in the window. For example, with the 40-column When setting the cursor position, the routine first checks
screen set for a full-size window (40 columns X 25 rows), this whether the specified position would be beyond either the
routine will return X and Y register values of 39 and 24, re- right or bottom margin of the window. If the position would
spectively. To return the proper values, the routine should be outside the window, the routine exits with the carry bit set
have added 1 to the subtraction results. By comparison, this and without changing the current cursor position. Thus, you
routine in Commodore 64 ROM, where is it called SCREEN, can check the carry bit after calling this routine to determine
returns the values 40 and 25 for the standard screen (also 40 whether the cursor was successfully moved (indicated by a
columns X 25 rows). clear carry bit).
This routine has an idiosyncrasy that will trip you up if
52330 $CC6A PLOT you're not careful. Keep in mind that the value in the X regis-
Reads or sets the current cursor position. ter contains the vertical (row) position, and the value in the Y
(This routine has a screen editOT jump table entry at 49176/$C018 register contains the horizontal (column) position. This is op-
and a Kernal jump table entry at 6552O/$FFF0.) posite from the way you normally think of x and y coordinates
Returns the row and column numbers corresponding to the in geometry: x is usually horizontal and y vertical. Some other
current cursor position or establishes new row and column routines, such as SCRORG [$CC5B], use X to hold the hori-
values, depending on the status of the carry bit upon entry. To zontal value and Y for the vertical value, so don't get
set the cursor position, enter the routine with the desired row confused.
number (0-24) in the X register, the desired column number
(0-39 for the 40-column screen or 0-79 for the 80-column 52386 $CCA2 KEYSET
screen) in the Y register, and the carry bit clear. To read the Defines a programmable function key.
cursor position, enter the routine with the carry bit set; the (This routine has a screen editor jump table entry at 49185/$CO21
current row number will be in the X register upon return, and and a Kemal jump table entry at 65381/$FF65.)
the current column number will be in the Y register (and also Replaces the existing definition string for one of the ten pro-
in the accumulator). grammable keys, F1-F8, SHIFT-RUN/STOP, and HELP, with
It's important to remember that coordinate numbering be- a new string. The routine first converts the key number (1-10),
gins with 0, not 1. Thus, setting the cursor position with X and in the X register upon entry, to a key index (0-9), which is
Y containing 5 and 3, respectively, will place the cursor on the stored in 220/SDC. The length of the definition string should
sixth row down at the fourth column across. When reading co- be in the Y register upon entry, and the address of the zero-
ordinates, remember that the cursor will actually be one posi- page pointer to the definition string should be in the accumu-
tion beyond the last character printed. The coordinates you set lator upon entry. The number of the memory bank where the
or read are relative to the home position and left margin of the definition string resides is read from the zero-page location im-
current window, not the absolute home position and left edge mediately following the two-byte pointer to the string. If the
318 319
52512 $CD20 $CD57 52567
length of the new definition string is the same as the length of 52524 $CD2C
the existing definition string for the specified key, no special Changes screen displays (ESC X).
handling is required; the new definition string is simply copied Stores the current character code in 240/$F0, then falls
over the old one. If the new definition is shorter, all the defi- through into the next routine to switch active displays.
nitions above the existing one are moved down. If the new
definition is longer, all characters must be moved upward. 52526 $CD2E SWAPPER
Before anything is actually moved, the routine checks to make
sure that adding the extra characters will not exceed the 246 Switches active screen displays.
bytes available for string definitions (4106-4351/$100A-$10FF). (This routine has a screen editor jump table entry at 49194/SC02A
and a Kernal jump table entry at 65375/SFF5R)
If the new definition will not fit, the routine exits with the sta- Swaps the active and inactive screen variables by exchanging
tus register carry bit set and without changing the existing def- the contents of 224-250/$E0-$FA with the contents of
inition string. 2624-2650/$0A40-$0A5A. (This duplicates the bug in the ini-
To add a new definition string, the length of the string is tialization routine [$C07B] which copies 27 values, when only
placed in the proper position in the string length table in bank 26 are actually valid.) The routine then swaps the active and
0 (4096-4105/$1000-$1009). Then characters are loaded from inactive tab stop and line link bitmaps by exchanging the
the new string in whatever bank it is located in by using the contents of 852-865/$0354-$0361 with the contents of
INDFET routine [$02A2]. They are stored at the proper posi- 2656-2669/$0A60-$0A6D. Finally, bit 7 of the active screen
tion in the definition string table (4106-4351/$100A-$10FF). flag (215/$D7) is toggled, switching the active and inactive
The status register carry bit is cleared before exit to indicate screen displays.
that the new definition string has been successfully added to Note that this doesn't physically turn either video chip on
the table. or off. Both video sources remain on at all times. The active
display is merely the one to which all printing is currently
directed.
52512 8CD20 52567 $CD57 CRSR80
Calculates the offset to the start of key definition string. Sets cursor position on 80-cohimn screen.
Adds the length table entries for all key definition strings with (This routine has a jump table entry at 49179/$C01B.)
an index lower than the one specified in the X register upon Checks active screen flag and exits immediately if the 40-
entry. (X should contain a key index, 0-9, not a key number, column screen is active. The screen memory address for the
1—10.) The total will be in the accumulator upon exit, and carry cursor position is calculated by adding the current cursor col-
will be set. Because there are no separator characters between umn (236/$EC) to the starting address for the screen line
definition strings in the table, the only way to determine the (224-225/$E0-$El), This address is then written to the 8563
starting position of a particular string is to add the lengths of chip's cursor position registers (R14-R15) using the routine at
all the preceding strings. This implies that an incorrect length 52684/$CDCC
value in the string length table (4096-4105/$1000-$1009) will This routine is normally called by the BSOUT exit routine
result in incorrect strings being returned for all keys with a [$C30E] after a character has been printed. The routine is nec-
higher index. Thus, you should use caution when changing essary because the 80-column cursor is managed in hardware,
string length tables directly. not software. So, unlike the 40-column display's cursor, it
doesn't move automatically when cursor row and column
pointers are changed.
320 321
52591 $CD6F $CDD8 52696
52591 $CD6F CRSRON sequential addresses. The routine works by loading X with
Turns cursor on. 31/$1F, the number of the 8563's data r e a d / w r i t e register.
Begins by checking the active screen flag. If the 40-column Then it falls through into the following routine to store the ac-
display is active, the routine merely clears the cursor enable cumulator contents in that register. Writing to register 31
flag (2599/$0A27) and exits. For the 80-column display, the causes the value written to be stored in the 80-column RAM
attribute of the current cursor position is read and stored in location addressed in registers 18-19.
2611/$0A33. The upper four bits (containing the printing style The following example shows h o w to use this routine to
information) are stored in 219/$DB. Then this style infor- copy the contents of the first 256 bytes of 40-column screen
mation is combined with the current cursor color (the lower memory (locations 1024-1279/$0400-$04FF) to 80-column
four bits of 241/$F1) to determine the new attribute for the screen memory:
cursor position. Finally, the cursor is enabled by writing the
current cursor style (stored in 2603/$0A2B) to the 8563 chip's 0B00 LDX #$12 ; Load registers 18 and 19
cursor control register (RIO). 0B02 LDA #$00 ; with low and high bytes of
OB04 JSR $CDCC ; 80-column screen starting
0B07 INX ; address ($0000).
52639 $CD9F CRSROFF 0B08 JSR $CDCC
Turns cursor off. 0B0B LDY #$00 ; Initialize loop offset.
Begins by checking the active screen flag. If the 80-column 0B0D LDA $0400,Y ; Read byte from 40-column screen,
display is active, this routine sets the update location registers 0B10 JSR $CDCA ; Store in 80-column RAM.
(R18-R19) to the address of the attribute for the current cursor 0B13 INY
0B14 BNE $0B0D ; Loop for 256 bytes.
position, then restores the cursor position to its original 0B16 RTS
attribute (stored in 2611/S0A33), Finally, the cursor is dis-
abled by writing the value 32/$20 to the 8563 chip's cursor 52684 $CDCC WRITEREG
control register (RIO). For the 40-column display, the cursor is
disabled by clearing the cursor enable flag (2599/$0A27). Writes to an 80-column chip register.
Then the blink phase flag (2598/$0A26) is checked to see Stores the accumulator contents in the 8563 register specified
whether the character under the cursor is in the normal or re- in the X register (see Chapter 8 for a description of the 8563's
versed portion of the blink sequence. If the character is in its registers). The accumulator and X register contents will not be
normal state, no further action is necessary. However, if the changed, and the Y register is unaffected. No error checking is
character is reversed, the blink phase flag is reset and the performed; when you use this routine you are responsible for
cursor position is restored to its original character and color making sure that X contains a valid register number (0-36/
(stored in 2601/S0A29 and 2602/$0A2A, respectively). $00-$24). This routine illustrates the proper procedure for
writing to an 8563 register: The desired register number is
52682 $CDCA WRITE80 stored in 54784/$D600. Then the routine waits until bit 7 of
that location is set to % 1 , after which the new register value is
Writes a byte value to 80-column chip memory. stored in location 54785/$D601.
Stores the value in the accumulator into a location in the 8563
chip's private 16K of RAM. The target memory address is 52696 $CDD8 READ80
specified by the current contents of the 8563's update location
registers (R18-R19). The contents of the X register will be Reads a byte value from 80-column chip memory.
changed, but the contents of the accumulator and Y register Reads the contents of a location in the 8563 chip's private 16K
are unaffected. The address in R18-R19 is automatically incre- of RAM. The target memory address is specified by the current
mented after a byte is written, so it is not necessary to update contents of the 8563's update location registers (R18-R19).
those registers before every byte when writing to a series of The location's contents will be in the accumulator upon exit
322
323
52698 SCDDA 52748
ecEoc
from this routine. The contents of the X register will be 52710 $CDE6 SCNPOS
changed, but the Y register is unaffected. The address in
R18-R19 is automatically incremented after a byte is read, so Sets the current address in 80-column screen memory.
it is not necessary to update those registers before every byte Loads the 8563 update location registers (R18-R19) with the
when reading a series of sequential addresses. The routine address of the screen memory location that corresponds to the
works by loading X with 31/$IF, the number of the 8563's current cursor position. Upon entry, the Y register should con-
data read/write register. Then it falls through into the follow- tain the offset to the current column. To calculate the memory
ing routine to load the accumulator with the contents of that address, this offset is added to the address of the first screen
register. Reading from register 31 returns the contents of the memory location for the current screen line (224-225/
80-column RAM location addressed in registers 18-19. $E0-$El). The registers are loaded by using the subroutine at
52684/$CDCC. Once the address is loaded into R18-R19, the
The following example shows how to use this routine to next value placed in the read/write register (R31) will be
copy the contents of the first 256 bytes of 80-column screen stored in the specified screen memory location.
memory to 40-column screen memory locations 1024-1279/
$0400-$04FF: 52729 $CDF9 ATTRPOS
0B00 LDX #$12 Load registers 18 and 19 Sets the current address in 80-column attribute memory.
0B02 LDA #$00 with low and high bytes of
0B04 JSR Loads the 8563 update location registers (R18-R19) with the
$CDCC 80-column screen starting
0B07 INX address ($0000). address of the attribute memory location that corresponds to
0B08 JSR $CDCC the current cursor position. Upon entry, the Y register should
0B0B LDY #$00 Initialize loop offset. contain the offset to the current column. To calculate the
0B0D JSR $CDD8 Read a byte from 80-column RAM. memory address, this offset is added to the address of the first
0B1O STA $0400,Y Store in 40-column screen memory. attribute memory location for the current screen line
0B13 INY (226-227/$E2-$E3), The registers are loaded by using the
0B14 BNE $0B0D Loop for 256 bytes. routine at 52684/$CDCC. Once the address is loaded into
0B16 RTS
la R18-R19, the next value placed in the read/write register
(R31) will be stored in the attribute memory location.
52698 $CDDA READREG
Reads from an 80-column chip register. 52748 SCEOC INIT80
Reads the current contents of the 8563 register specified in the Initializes character definitions for 80-column screen.
X register. The register value will be in the accumulator upon (This routine has a screen editor jump table entry at 49191/SC027
exit from this routine. See Chapter 8 for a description of the and a Kernal jump table entry at 65378/$FF62.)
8563's registers. The X register contents will not be changed, Copies the contents of the character generator ROM (at
and the Y register is unaffected. No error checking is per- 53248-57343/$D000-$DFFF in bank 14) to the character defi-
formed; when you use this routine you are responsible for nition area at 8l92-16383/$2000-$3FFF in the 80-column
making sure that X contains a valid register number (0-36/ video chip's private block of RAM (which is not part of the
$00-$24). This routine illustrates the proper procedure for 8502 microprocessor's address space). This is necessary be-
reading an 8563 register: The desired register number is stored cause the 8563 chip has no character ROM of its own. Because
in 54784/SD600. Then the routine waits until bit 7 of that lo- the 8563 uses 16-byte character definitions, each 8-byre char-
cation is set to % 1 , after which the register value can be read acter definition from ROM is padded with eight zeros when
from location 54785/$D601. copied to 8563 RAM. See Chapter 8 for information on how
the 80-column characters can be redefined.
In the 128's ROM, this routine is called only by the
Kernal IOIN1T routine [$E109], which is part of both the reset
324 325
52812
$CE4C SCE5C 52828
As an example of how you would use this table to trans- 52904 $CEA8 KEYDEFS
late color numbers, suppose you had a 40-column color num-
ber in the accumulator and needed to know the equivalent 80- Table of standard function key definitions.
column color number. All that's needed is The first ten bytes here hold the lengths of the following ten
key definition strings. The screen editor initialization routine
TAX [SC07B] copies these lengths and strings to the definition area
LDA $CE5C,X
at 4096/$1000. The text for the standard definitions is as
52844 $CE6C follows:
MASKTBL Key Definition
Table of bit mask values.
Fl GRAPHIC
Each of the eight bytes in this table has only one bit set to F2 DLOAD"
% 1 . The mask values are used to decode bitmapped tables F3 DIRECTORY {RETURN}
such as the ones for tab stops and line links. The binary F4 SCNCLRjRETURN}
equivalents of the table bytes, in order, are as follows: F5 DSAVE"
%10000000 F6 RUN {RETURN}
%01000000 F7 LIST{RETURN}
%00100000 F8 MONITOR {RETURN}
%00010000 SHIFT-RUN/STOP DL"*{RETURN}RUN{RETURN}
%00001000 HELP HELP {RETURN}
%00000100 If you ever need to restore the standard key definitions, you
%0 0000010
%00000001 can recopy the contents of this table into the definition area.
In BASIC, the required program line would have this form:
BANK 15: FOR 1=0 TO 76: POKE 4096+I,PEEK(52904+I): NEXT I
52852 $CE74 VARTBL
Tables of default screen editor variables. 52981-53247 $CEF5-$CFFF Unused
Locations 52852-52877/$CE74-$CE8D hold the default
screen editor variable settings for the 40-column screen. Loca- All locations in this unused area of ROM are filled with the
tions 52878-52903/$CE8E-$CEA7 hold the default settings value 255/$FF, except for the final two, which are $00 $C3.
for the 80-column screen. The screen editor initialization rou- Ideally, the keyboard decoding tables would have been placed
tine [$C07B] copies the values for the default screen—deter- here following the screen editor routines so that the screen
mined by the position of the keyboard 40/80 DISPLAY key— editor package could be fully self-contained in this block of
into the active screen variable table at 224-249/$E0-$F9, and ROM. However, there's not sufficient room here for the five
the values for the other screen into the inactive screen table at 89-byte keyboard tables, so they were placed at the end of
2624-2649/$0A40-$0A59. Thus, the values in these tables de- Kernal ROM (64128-64572/$FA80-$FC3C).
termine the variable settings after power-on, reset, or
RUN/STOP-RESTORE.
Actually, due to a bug in the initialization routine, one
byte too many is copied when the tables are transferred to
RAM. Thus, the byte following the active screen default value
table will be copied to 250/SFA, and the byte following the
inactive screen default table will be copied to 2650/$0A5A.
328
329
I/O Chip Registers,
Color RAM, and
Character ROM
Bits 0 and 4-5 of the MMU configuration register (65280/
$FF00) determine what is visible in the area between addresses
53248-57343/$DO00-$DFFF of the 128's memory space. If bit
0 of the configuration register is %0, the collection of hard-
ware registers and 40-column color RAM known as the I/O
block is visible, regardless of the setting of bits 4 and 5 of the
register. The I/O block includes the following elements:
53248-53296/$D00O-$D030 VIC (40-column) video chip registers
54272-54300/$D400-$D41C SID sound chip registers
54528-54539/$D500-$D50B MMU chip registers
54784-54785/$D600-$D601 VDC {80-cohimn) video chip registers
55296-56319/$D800-$DBFF Color RAM for VIC chip
56320-56335/$DC00-$DC0F CIA chip registers (CIA #1)
56576-56591/$DD00-$DD0F CIA chip registers (CIA #2)
57088-57098/$DF0O-$DFOA REC expansion controller chip regis-
ters (if memory-expansion module
connected)
If bit 0 of the configuration register is set to % 1 , the set-
ting of bits 4 and 5 will determine what is visible in this area.
(Actually, these bits control what is seen in the entire area
from 49152-65535/$C000-$FFFF.) The four possible selec-
tions for 53248-57343/$D000-$DFFF are as follows:
Bits Block contents
5 4
0 0 Character ROM
0 1 Internal function ROM
1 0 External function ROM
1 1 RAM
Character ROM contains the bit patterns to define the shape
of the letters, numbers, and symbols for the video displays.
When RAM is selected, the RAM block from which the mem-
ory is seen is determined by the setting of bits 6 and 7 of the
333
configuration register. The I/O block is visible in all standard
bank configurations except banks 0-3, which are all RAM, and Video Fundamentals
bank 14, where character ROM is seen. The output signals from the VIC chip tell the video device
A bit of 128 hardware trivia: Since the MMU configura- (monitor or television) how to draw the screen display. To un-
tion register setting in bits 4-5 for character ROM is also the derstand the operation of the VIC chip, you need to under-
one which selects screen editor ROM at 49152-53247/ stand a few of the fundamentals of video displays. The display
$C000-$CFFF and Kemal ROM at 57344-65535/$E000-$FFFF, is drawn on the monitor or television picture tube by a "gun"
you might expect that character patterns are stored between that shoots a beam of electrons at the screen. Where the beam
the screen editor and Kernal routines in the 16K ROM chip strikes the face of the screen, a spot on the screen's phospho-
designated U35. However, this is not the case. Character pat- rescent coating glows briefly. The electron gun doesn't just
terns are stored in a separate 4K ROM chip, designated U18. spray electrons at random; the beam is moved in a precisely
So what's between 53248-57343/$D000-$DFFF in the ROM controlled pattern. Beginning in the upper left corner of the
chip containing the screen editor and Kernal? That's where the screen, the beam is scanned (moved) horizontally across to the
ROM routines for CP/M mode are stored. The memory-shuf- right edge of the screen, drawing a very thin line of dots. It is
fling capabilities of the MMU and PLA allow this area of ROM then blanked while it is moved back to the left edge, but just
to appear at addresses 0-4095/$0000-$0FFF when CP/M below the top line. The beam is then scanned horizontally
mode is selected. Because this section of ROM is always invisi- across the screen again, and the process is repeated until the
ble to 128 mode, it is not covered further in this book. stack of thin lines fills the screen display.
Actually, for a color display there are three separate
beams working in conjunction to draw each line—one each
VIC (Video Interface Controller) Chip for the colors red, green, and blue. Each dot in the thin screen
line consists of red, green, and blue points. When the relative
53248-53296/$D000-$D030 intensities of the red, green, and blue points are varied, the
The chip whose registers appear in this area of the I/O block dot can take on a variety of hues. The VIC chip can produce
is referred to in Commodore literature as the VIC, even 16 different colors. Whenever a memory location or VIC regis-
though it is not exactly the same as the chip with that des- ter calls for a color value, the color is specified by a value in
ignation in the Commodore 64. However, the chip does pro- the range 0-15. Table 8-1 lists the standard designations for
vide the same 40-column video display features as its the VIC chip colors.
Commodore 64 predecessor. The differences are in the chip's
less familiar, but equally vital function of providing all the Table 8-1. Standard VIC Color Values
basic riming signals required by the system. The 128's version
of the VIC chip also supports the scanning of the additional 24 Value Color Value Color
keys on the 128's keyboard. For these new features, the 128 0/$00 black 8/$08 orange
version of the VIC has two more registers than its Commodore l/$01 white 9/$09 brown
2/$02 red 10/$OA light red
64 counterpart (49 instead of 47). There are actually two dif-
3/$03 cyan ll/$0B dark gray
ferent versions of the 128 VIC chip, depending on the video 12/$0C medium gray
4/$04 purple
system required in the country where the computer is sold. green 13/$0D light green
For NTSC (North American) video, the version is officially 5/$05
6/$06 blue 14/$0E light blue
designated the 8564 chip, while the PAL (European) model is 7/$07 yellow 15/$0F light gray
designated the 8566. All the registers described below operate
the same on both chips; only the video signal format is different. The stack of horizontal video lines is called the raster
(from the Latin word for rake—the pattern of evenly spaced
parallel lines is similar to that produced by pulling a rake
through soil). The individual lines are called raster scan lines.
334
335
The number of lines required for a full screen depends on the is in the degree of control over individual pixels. The bitmapped
video system in use. The North American (NTSC) version of (high-resolution) modes allow you to determine the color of
the VIC chip draws a raster of 264 scan lines, while the Euro- each pixel individually, while the character (low-resolution)
pean (PAL) version draws 313. Since the screen phosphor modes only allow control of groups of pixels. The tradeoff is
glows only briefly when struck by the raster beam, the screen that the character display modes use much less memory.
must be constantly redrawn. The rate of redrawing also de-
pends on the video system: 60 times per second for NTSC sys- Video Banks
tems or 50 times per second for PAL systems. Not all of these Before you read a discussion of the display modes, it's impor-
raster lines are used for the active video display. Most televi- tant to understand how the VIC chip sees memory. The VIC
sions and monitors overscan. That is, some raster lines at the uses the same RAM as the 8502 microprocessor, but it views
top, bottom, or both are actually drawn off the screen. The the memory very differently. The VIC chip has only 14 ad-
VIC compensates by restricting the active portion of the dis- dress lines compared to the processor's 16. This means that
play, the area where characters and graphics can be displayed, the VIC can, at any given time, address only 16K (16384
to 200 lines in the middle of the raster for both NTSC and bytes) out of the 64K of RAM in a block. The 16K area seen
PAL systems. (This can be reduced to 192 lines. For details, by the VIC chip is referred to as a video bank, not to be con-
see the entry for 53265/$D011.) The inactive lines form the fused with one of the processor's bank configurations—there
top and bottom portions of the border, a solid-color frame is no relationship. All of the information for the VIC screen
around the active screen. display must be visible within the same video bank. There are
The horizontal dots that make up each scan line are called four possible video banks per 64K block, or a total of eight
pixels (short for picture elements). The number of pixels in a possible video banks in the two RAM blocks in the 128. Bits
scan line depends on the screen mode, and is limited by the 0-1 of the CIA #2 register at 56576/$DD00 select one of the
speed at which the VIC chip can read data from memory. In four banks, and bit 6 of the MMU register at 54534/$D506 se-
the standard two-color modes, where a single bit determines lects which 64K-RAM block the video bank will be seen in.
the pixel color, the VIC chip draws 320 active pixels per scan Refer to the entries for those locations later in this chapter for
line. In the four-color (multicolor) modes, two bits are required more details. The base (starting) addresses for the banks are as
to specify the color of each pixel. Since the VIC must read follows:
twice as much data per pixel, only half as many pixels can be Bank Base address
drawn in the time allotted for a single scan line. As a result, 0 0/$0000
the multicolor modes have only 160 active pixels per scan line. 1 16384/S4000
The display is still the same size; the pixels are twice as wide. 2 32768/$8000
{The screen width can also be reduced to 304 standard pixels 3 49152/$C000
or 152 multicolor pixels. For details, see the entry for 53270/
$D016.) Just as the VIC draws extra lines above and below the Character Display Modes
active ones, it also draws extra pixels to the left and right of The VIC provides three character display modes: standard,
the active ones. The inactive pixels form the sides of the solid- multicolor, and extended background color. The standard
color border. character display mode is the default system for the VIC—the
The VIC chip supports two major classes of display one which is active when no other mode is selected. The other
modes—character and bitmapped. These are also referred to two modes are not directly supported by the 128 operating
as low resolution and high resolution, but that's somewhat system (there's no GRAPHIC statement to select these modes),
misleading, since both provide the same active screen areas— so you must enable them by directly setting the appropriate
320 pixels X 200 lines for standard modes or 160 pixels X 200 bits in VIC registers. As a result, those modes are a bit more
lines for multicolor modes. The difference between the classes difficult to use effectively.
336 337
For a standard (GRAPHIC 0) character display, the 320- acter position on the screen. Unlike the case of screen and
pixel X 200-line active screen area is divided into 1000 8-pixel character memory, however, the location of VIC color memory
X 8-line character positions, arranged as 25 rows with 40 is fixed and does not have to be within the current video bank.
character positions per row. The contents of the character po- It always appears to the processor at locations 55296-56319/
sitions are determined by values stored in a 1000-byte area of $D800-$DBFF in the 1/0 block. Refer to the section on color
screen memory (sometimes referred to as the video matrix). memory later in this chapter for details.
Each location in screen memory corresponds to a single char- The procedure for displaying the character A in blue at
acter position on the screen. The value in a screen memory lo- the upper left corner of the screen would be something like
cation selects one of 256 standard character-pattern definitions this: The VIC looks to the first location of screen memory to
to be drawn in the corresponding character position. The determine which character pattern to display in that position.
screen memory values are referred to as screen codes, and The screen code for A is 1, so this value is used as an index to
they are not the same as character codes. See Appendix C for the eight-byte pattern definition in character memory. The VIC
a list of screen codes and corresponding character patterns. then looks to the first location of color memory and proceeds
The location of screen memory within the current video bank to draw pixels in the color specified there (6 for blue) for all
is controlled by bits 4-7 of the VIC register at 53272/$D018. %1 bits in the pattern. For all %0 bits, pixels are drawn in the
See the entry for that register for details. color specified in the background color register. Figure 8-1
The pattern definitions come from another area of mem- illustrates the process.
ory known as character memory. As mentioned above, each
character position consists of eight scan lines with eight pixels Figure 8-1. Standard Character Display Mode
per line—a total of 64 pixels per position. In standard charac-
ter mode, a pixel can be one of two colors, so only one bit
(which can be either %0 or %1) is required per pixel. Thus, a
character-pattern definition requires 64 bits, or eight bytes.
The pixels represented by %0 bits in the pattern definition are
drawn in what is referred to as the background color, which is
common to all screen positions. The pixels represented by %1
bits are drawn in what is referred to as the foreground color,
which can be independently selected for each character posi-
tion. The location of character-pattern memory within the cur-
rent video bank is controlled by bits 1-3 of the VIC register at
53272/SD018. See the entry for that register for more details.
Standard character definitions for the 128 come from the char-
acter ROM. This ROM is located beginning at address 53248/
$D000 in the system's address space, but can be made visible
in any video bank. See the section on character ROM later in
this chapter for more information.
The background color for %0 bits in all character posi-
tions is determined by the value in the VIC register at
53281/$D02I. The foreground color for the %1 bits in each
character position is determined by values in another 1000-
byte area of memory known as color memory. As in screen
memory, each location in color memory corresponds to a char-
339
Custom Characters 600 FOR 1 = 0 TO 7
You are not limited just to the character patterns provided in 610 READ A
the ROM. It is relatively simple to design your own characters. 620 POKE 8192 + (8 * 28) + I,A
However, using custom characters is an all-or-nothing affair. 630 NEXT
Once you switch off the standard ROM-based character set, 640 DATA 24,60,102,96,102,60,24,0
you must provide definitions for every character you wish to This example assumes that character memory has previously
use. You must begin by selecting the area of RAM where you been relocated to address 8192/$2000.
will place the new character set. See the entry for the register
at 53272/$D018 for details. If you only want to use a few cus- Figure 8-2. Custom Character Design Grid
tom characters while retaining the majority of the standard
% D0011000 = 24/$18
character set, the next step is to copy the standard character
% 00111100 = 60/$3C
patterns from ROM to the selected RAM area. If you do this,
% 01100110 = 102/$66
you'll only have to provide custom pattern information for
% 01100000 = 96/$60
those characters you wish to redefine.
"A011001IO = 102/S66
To calculate the proper byte values for a custom character % 00111100 = 60/S3C
definition, use an 8 X 8 grid as shown in Figure 8-2. Fill in % 00011000 = 24/S1B
the grid squares for those pixels you wish to have displayed in % 00000000 = 0/$00
the foreground color. Unless you are designing patterns that
will connect with adjacent patterns (such as the line segments
in the standard character set), it is customary to leave at least Multicolor Character Mode
one row and one column of the pattern blank to provide some Multicolor character mode is similar in operation to standard
horizontal and vertical separation between characters. The character mode. The difference is that each multicolor charac-
ROM patterns for the standard letters and numbers don't fill ter position consists of 4 pixels X 8 lines (instead of 8 X 8).
in any pixels in the leftmost column, and only lowercase char- The number of positions remains the same (25 rows X 40 col-
acters with descenders (g, j, p, q, and y) use the bottom row. umns) and the positions are the same size, but now each pixel
To calculate the binary bit pattern for each row of the pat- is twice as wide (there are only 160 pixels per raster line).
tern, use a %0 for each blank (background) pixel and a %1 for However, each pixel can be one of four colors instead of just
each filled (foreground) pixel. Next, convert the binary bit pat- one of two colors. Screen memory still holds pointers to pat-
tern to a number (use the machine language monitor's number- tern definitions in character memory, but the pattern infor-
conversion feature if you're not handy with binary). The final mation is interpreted differently. It now takes two bits per
step is to store the resulting eight values in the character pixel to select the color instead of just one, but since there are
memory locations for the pattern you are changing. The sim- only half as many pixels per pattern, the number of bits re-
ple formula for finding the starting address in character mem- quired for each definition remains the same (2 bits per pixel *
ory of the pattern for any character is: 4 pixels * 8 lines = 64 bits).
pattern address = character base address + (8 * screen code) To select multicolor character mode, you must set bit 4 of
the VIC register at location 53270/$D016. However, there's a
The character base address is the starting address of character problem here because the screen editor IRQ routine always re-
memory (see the entry for 53272/$D018). For example, to re- sets this bit to %0 when setting up the text screen (see the sec-
place the British pound symbol (£, screen code 28/$lC) with tion below on the screen editor IRQ routine). To prevent this,
the pattern shown in Figure 8-2, you could use statements like you must turn off the screen-setup portion of the IRQ by stor-
the following: ing the value 255/$FF in location 216/SD8. Setting the VIC
register bit makes it possible to enable multicolor character
340 341
mode for any or all screen positions, but it doesn't actually
switch any screen positions to multicolor mode. Multicolor Desired %11 bit color Value to store in color memory
mode must be enabled individually for each character position black 8/$08
white 9/$09
on the screen. The controlling factor is bit 3 of the color mem- red
ory location for each character position. When that bit is %0 10/$0A
cyan ll/$0B
in a color memory position, the corresponding character posi- purple 12/$0C
tion on the screen remains in standard character mode, so it is green 13/$0D
possible to intermix standard and multicolor character modes blue 14/$0E
on the same screen display. However, only bits 0-2 of the yellow 15/$0F
color memory location are now available to hold color values,
so the foreground color for standard mode positions in a mul- Because the standard character sets were not designed to
ticolor display is limited to the first eight values in Table 8-1— be displayed in multicolor character mode, any text printed to
black-yellow, values 1-7. To select multicolor character mode the screen in this mode will be at best barely legible. As a re-
for a screen position, you must set bit 3 of the corresponding sult, multicolor mode is practical only when you are using cus-
color memory location to % 1 . That is, you must store a value tom characters designed specifically for this mode. The rules
of 8 or greater in the location. for designing custom characters for multicolor mode are the
When a multicolor character is drawn, all pixels in the same as for the standard character mode, except that you de-
pattern represented by %00 bit pairs will be drawn in the sign the characters in a 4 X 8 grid, as shown in Figure 8-3.
background color specified in the VIC register at 53281/
$D021. All pixels represented by %01 bit pairs will be drawn
in the color specified by the value in the register at 53282/ Figure 8-3. Multicolor Character Design Grid
$D022, and all pixels for %10 bit pairs will be drawn in the
color specified in the register at 53283/$D023. All of these
registers can take any of the 16 standard colors listed in Table = %00 Dl 01 00 = 20/S14
8-1, but since the registers are common to all positions, the
color for pixels with %00, %01, and %10 patterns will be the = %00 10 10 00 = 40/$28
same for all characters. However, the color for pixels with
%11 bit patterns can be specified individually for each screen - %01 10 10 01 = 105/$69
position in the corresponding color memory location. Since bit
3 of the color memory location is used to specify multicolor = <ftl0 11 11 10 = 190/SBE
mode, only bits 0-2 are available to hold color values. As a re-
sult, only the first eight colors are available. But since bit 3 - 1410 11 11 10 = 190/SBE
must be set to % 1 , the values you store in color memory to
achieve these colors are different from the standard values. For = %01 10 10 01 = 105/$69
multicolor character mode, the values to store in color memory
to select the available colors for %11 bits are as follows: « %00 10 10 00 = 40/$28
= %00 01 01 00 = 20/$14
342
343
Each grid position can hold one of four two-bit values unique screen code values (0-63), so only the first 64 eight-bit
representing the four color choices: pattern definitions in character memory are used in this mode.
%00 Background color 0 (common to all characters) For example, screen memory values of l/$01, 65/$41, 129/$81,
%01 Background color 1 (common to all characters) and 193/$C1 all produce the same character (screen code 1,
%10 Background color 2 (common to all characters) the letter A in the standard character set), but each provides a
%11 Foreground color {independently selectable for all characters, different background color for that character.
but only eight colors are available)
Once the design is completed, the byte values for the charac- Bitmapped Display Modes
ter-pattern definition are calculated just as for standard charac- The VIC provides for two bitmapped modes: standard and
ter mode. multicolor. In these modes, the state of each pixel in the
screen display can be controlled independently. The standard
Extended Background Color Mode bitmapped mode allows you to select one of two colors for
The third character mode, extended background color mode, is each pixel, while the multicolor mode allows you to chose
selected by setting bit 6 of the VIC register at 53265/$D011 to from among four colors. Both modes are supported by the op-
% 1 . It also uses the same fundamental elements as standard erating system: standard bitmapped mode as GRAPHIC 1 (or,
character mode: screen memory, character memory, and color with a text window, as GRAPHIC 2) and multicolor bit-
memory. As in standard character mode, the extended back- mapped mode as GRAPHIC 3 (or, with a text window, as
ground color mode screen is divided into a 25-row X 40-column GRAPHIC 4).
grid of 8-pixel X 8-line character positions. As in standard Standard bitmapped mode is selected when bit 5 of the
character mode, each position has a corresponding screen VIC register at 53271/$D017 is set to %1 (but see the section
memory location that holds a value indicating which pattern below on the screen editor IRQ for information about the
from character memory is to be drawn in the position. And, as shadow for this bit). This mode provides for 320 horizontal
in standard character mode, each character position on the pixels per line, each of which can be one of two colors. A sin-
screen takes its foreground color (the color for pixels repre- gle bit is required to specify the color of each pixel, so 320 *
sented by % 1 bits in the character pattern) from the value in a 200, or 64,000 bits, are required to "map" the entire display
corresponding color memory location. The difference is that area. At 8 bits per byte, 8000 bytes are required for the bit-
extended background color mode allows you to select from map. This is half of the available space in the 16K video bank.
among four different background colors for the pixels repre- The starting address of the bitmap is specified in bit 3 of the
sented by %0 bits in the character patterns. register at 53272/$D018.
The background color for each position is specified by bits The VIC's scheme for mapping the screen is simple for
6-7 of the screen code for the position. These bits select which the chip (it's a variation of character mode), but it's rather
of the four background color registers will specify the back- complicated for the programmer. As you would expect, the
ground color for the position: first eight pixels on the screen, starting in the upper left corner
Bits Background color source of the first vertical line, are controlled by the eight bits of the
7 6 first byte of the bitmap. However, the next eight pixels are
0 0 background color register 0 (53281/$D021) controlled by the bits of the ninth byte. The bits of the second
0 1 background color register 1 (53282/$D022) through eighth bytes in the bitmap control the leftmost eight
1 0 background color register 2 (53283/SD023) pixels of the second through eighth vertical lines. This scheme
1 1 background color register 3 (53284/$D024) is repeated across the screen. Figure 8-4 illustrates the offsets
Since the highest two bits of each screen memory location from the bitmap starting address for the bytes which control
are used to specify background color, only bits 0-5 are avail- the pixels in the upper left corner of the screen.
able to hold screen code data. Thus, there are only 64 different
344 345
Figure 8-4. Byte Offsets for Bitmapped Screen where x will have a value in the range 0-319 and y will have
a value in the range 0-199.
0 B 16 Each bit in the bitmap can be either %0 or % 1 , so each
1 9 17 corresponding pixel on the screen can be one of two colors. By
2 10 18 convention, the color specified by a %0 bit is referred to as the
3 11 19 background color and the color specified by a %1 bit is re-
4 12 20 ferred to as the foreground color. The values for both colors
5 13 21 come from the video matrix, the area used as screen memory
6 14 22 in the character display modes. (Color memory and the back-
7 IS 23 ground color registers are not used in standard bitmapped
320 328 336 mode.) The low nybble (bits 0-3) of a video matrix location
321 329 337 holds the background color value and the high nybble (bits
322 330 338 4-7) holds the foreground color value. Either foreground or
323 331 339 background can take any of the 16 colors listed in Table 8-1.
324 332 340 However, since there are only 1000 video matrix positions, the
325 333 341 foreground and background color cannot be specified individ-
326 334 342 ually for each of the 64,000 pixels on the screen. All 64 pixels
327 335 | 343 within an 8-pixel X 8-line area will share foreground and
640 648 656 background colors. The common areas are arranged in the
641 649 657 same fashion as screen memory: 25 rows X 40 coiumns.^ To
642 650 658 determine the video matrix location that holds the color infor-
643 651 659 mation for a particular x,y coordinate, use the following
644 652 660 formula:
645 653 661 color byte = 40 * INT(y / 8) + INT(x / 8) + screen base address
646 654 662
647 |_ 655 663 Multicolor Bitmapped Mode
960 968 976 Multicolor bitmapped mode is similar to bitmapped mode, but
the number of possible colors per common color area is in-
creased to four. To select among four different colors, two bits
This obviously isn't very convenient. Most programmers are required for each pixel. Since twice as many bits are re-
prefer to use a more familiar ^-coordinate system, as shown quired to specify the color of each horizontal pixel, only half
in Figure 8-5. In this system, the horizontal (x) pixel position as many pixels can be displayed per line; horizontal resolution
will be in the range 0-319 and the vertical {y) position will be is reduced to 160 pixels per line. The display will still be the
in the range 0-199. In x,y format, the upper left corner of the same size, but each pixel will now be twice as wide. To deter-
screen is position 0,0 and the lower right corner is position mine the byte offset (0-7999) within the bitmap and the bit
319,199. This is also the format used to specify screen posi- pair (0-3) within that byte which correspond to a particular
tions in BASIC statements such as BOX, CIRCLE, and DRAW, ^-coordinate pair, use the following formulae:
To determine the byte offset (0-7999) within the bitmap and byte offset = 40 * (y AND 248) + 2 * (x AND 252) + (y AND 7)
the bit (0-7) within that byte which corresponds to a particu- bit pair = 3 - (x AND 3)
lar ^-coordinate pair, use the following formulae: where x will have a value in the range 0-159 and y will have
byte offset = 40 * (y AND 248) + (x AND 504) + (y AND 7) a value in the range 0-199.
bit = 7 - (x AND 7)
346 347
Of the four color sources in multicolor mode, one is com- wide. Sprites can also be doubled in size horizontally or verti-
mon to all pixels on the screen and the other three can be se- cally (see the registers at 53271/$D017 and 53277/$D01D).
lected independently for each common color area. Common The rules for defining sprite bit patterns are the same as
color areas correspond in size {4 pixels X 8 lines) and layout for custom characters in the corresponding screen modes. Each
(40 X 25) to multicolor character positions. All pixels repre- standard sprite pixel is represented by one bit in a pattern bit-
sented by %00 bit patterns in the bitmap will take the color map, while each multicolor sprite pixel requires two bits.
specified in the VIC background color register at 53281/ Thus, three bytes are required to define each scan line of the
$D021. As in standard bitmapped mode, the video matrix pattern, and each sprite pattern definition requires 3 * 21, or
(screen memory) area holds color information. In this case, the 63 bytes. The rules for calculating byte values are the same as
lower nybble (bits 0-3) of each video matrix location specifies for custom character patterns. Figure 8-5 shows a sprite design
the color for all %10 bit patterns within the corresponding grid.
common color area, while the upper nybble (bits 4-7) specifies
the color for alt %01 bit patterns in the common color area. Figure 8-5. Sprite Design Grid
The color for any %11 bit patterns in each common color area
is determined by the value in the corresponding color memory
location (55296-56295/$D800-$DBE7). Any of these color
sources can take any of the 16 color values listed in Table 8-1.
Sprites
Sprites, which Commodore officially calls movable object
blocks (MOBs), are a special feature of the VIC. As their offi-
cial name implies, sprites are images that can be easily moved
about on the screen. Sprites are completely independent of the
background display, and can be made to appear either in front
of or behind screen foreground objects. They can move with
equal ease over character and bitmapped screens. The manipu-
lation of sprites consumes a substantial portion of the VIC
chip's internal hardware. You'll notice in the discussion of VIC
registers that 34 of the chip's 49 registers are used for some
sort of sprite manipulation. This section uses the standard VIC
number designations, 0-7, for the eight sprites. BASIC, on the
other hand, uses sprite numbers 1-8. Add 1 to the VIC sprite
number to get the corresponding BASIC sprite number, or
subtract 1 to convert the BASIC sprite number to a VIC sprite
number.
Sprites have the same two basic modes as screen displays:
standard and multicolor. Standard sprites are 24 pixels wide X For standard sprites, all pixels represented by %0 bits in
21 scan lines tall, and can have only one color. Multicolor the definition pattern will be transparent. That is, whatever is
sprites are 12 pixels wide X 21 scan lines tall, and can have on the screen behind the sprite will show through. Pixels rep-
three colors. However, multicolor sprites are the same size as resented by %1 bits take the color specified in the color regis-
standard sprites because the multicolor pixels are twice as ter for that sprite (53287-53294/$D027-$D02E), so each sprite
can take a different sprite foreground color. For multicolor
348 349
sprites, pixels represented by %00 bit patterns are transparent. ters at 53248-53264/$D000-$D010. Refer to the discussion of
Pixels represented by %01 and %11 patterns take the colors those registers for details.
specified in the sprite multicolor registers (53285/$D025 and When two sprites positions' overlap, one will appear in
53286/$D026, respectively). These colors are common to all front of the other. The one that appears in front is said to
eight sprites. Multicolor pixels represented by %10 bit patterns have higher priority. The priority of the sprites in relation to
take the color specified in the sprite foreground color registers. each other is fixed. Sprite 0 has the highest priority, and will
The 63 data bytes for the sprite pattern can't be placed appear in front of any other sprites it may overlap. Sprite 1
just anywhere in memory. The definitions must be located has the next highest priority; it can appear in front of any
within the current VIC video bank, and must begin at an ad- sprite except sprite 0. The priority decreases with increasing
dress which is an exact multiple of 64. A 16K VIC video bank sprite number, down to sprite 7, which appears behind any
other sprite it may overlap. The priority of sprites in relation-
has room for 16384 / 64, or 256 sprite patterns. The pattern
ship to screen foreground objects is programmable; sprites can
for each of the eight sprites is determined by the value in a
appear to pass either in front of or behind screen foreground
corresponding sprite pointer. The sprite pointers don't occupy pixels. See the discussion of the register at 53275/$D01B for
any fixed locations. Rather, they are found at the highest eight details.
locations of the current screen memory (video matrix) area, at
offsets of 1016-1023 bytes from the start of the area. The When two sprites overlap, or when a sprite overlaps
screen foreground pixels, a collision is said to occur. The VIC
pointer value (0-255) selects one of the 256 sprite pattern
records these collisions automatically, and can generate inter-
areas. The relationship between pointer values and definition
rupts as a result. See the discussion of the registers at
pattern area starting addresses is as follows: 53278-53279/$D01E-$D01F.
pointer value = pattern starting address / 64
or: Screen IRQ Routines
pattern starting address = pointer value * 64 The 128 introduces a feature that may be unfamiliar to those
with previous Commodore experience: shadow registers. A
The 128 reserves locations 3584-4095/$0E00-$OFFF in shadow register is a RAM memory location that is copied into
block 0 RAM to hold sprite pattern data. This 512-byte area a hardware register at regular intervals. Shadow registers are a
provides room for eight patterns, one for each of the eight feature of the system's software, not its hardware. The system
sprites. The sprite pointers are initialized to point to patterns IRQ interrupt sequence, the collection of routines executed ev-
in this area as follows: ery 1/60 second (1/50 second in PAL systems), includes two
Sprite Pointer value Pattern address separate sections which affect the VIC chip. The screen editor
0 56/$38 3584-3647/$0E00-$0E3F IRQ routine [$C194] controls the screen mode and raster inter-
1 57/$39 3648-371l/$0E40-$0E7F rupt, and the BASIC IRQ routine [$A84D] controls sprite
2 58/$3A 3712-3775/$0E80-$0EBF movement, detects sprite collisions, and reads the light pen.
3 59/$3B 3776-3839/$0ECO-$0EFF Because these routines maintain shadows of some VIC regis-
4 60/$3C 384O-3903/$0F0O-$0F3F ters, the registers cannot be changed directly while the normal
5 61/$3D 3904-3967/$0F40-$0F7F interrupt sequence is active. If you try to store a new value in
6 62/$3E 3968-403l/$0F80-$0FBF a register that has a shadow, the interrupt will replace your
7 63/$3F 4032-4095/$0FC0-$0FFF value with the shadow register contents at the next system
Even after a sprite is assigned a pattern, it will not appear IRQ interrupt—within 1/60 second. The discussion of the VIC
on the screen until it is enabled and moved into the visible registers below notes which registers have shadows and ex-
area of the screen display. Sprites are enabled by setting the plains how to go about changing such registers. Refer to the
appropriate bits in the register at 53269/$D0l5. The position appropriate ROM routine entry for more information on the
of each sprite on the screen is specified by values in the regis- interrupt routines.
350 351
53248 $D000 SD010 53264
Sprite Horizontal Bit in Vertical greater than 255, which is the largest value that can be stored
register $D010 register in a horizontal position register. To move a sprite to horizontal
0 53248/$DO00 0 53249/$D001 position 256, you must set the horizontal position register to
1 53250/$D002 1 53251/$D003 0/$00 and set the most significant horizontal bit for that sprite
2 53252/$D004 2 53253/$D005
3 53254/$D006 3
(in the register at 53264/$D010) to % 1 . The most significant
53255/$D007 bit must remain set for all positions greater than 255. Because
4 53256/$D008 4 53257/$D009
5 53258/$DO0A 5 53259/$D00B
of the extra programming required to move the sprite to this
6 53260/$DOOC 6 53261/$D00D right portion of the screen, the vertical column at horizontal
7 53262/SDOOE 7 53263/SD00F position 256 is frequently referred to as the seam.
The values in these registers specify a sprite's position on The values in these registers cannot be changed directly
the screen. (Actually, the values set the position of the upper while the normal BASIC IRQ routine [$A84D] is in use. That
left corner of the 24 X 21-pixel sprite pattern.) The coordinate routine copies the contents of the shadow sprite position loca-
system used is slightly different from the one used for bit- tions (4566-4582/$llD6-$llE6) into these registers during
mapped graphics, as illustrated in Figure 8-6. Note that the each system IRQ interrupt. (See the discussion of the BASIC
sprite coordinate system remains the same regardless of the IRQ routine in Chapter 5 for more details.) There are two
current screen mode (character or bitmapped) or sprite mode ways to deal with this. The simplest solution is to store the
(standard or multicolor). desired sprite position values in the proper shadow location
(see the entry for the shadow locations in Chapter 3). If you
wish to use the true registers, you can prevent the execution of
Figure 8-6. Sprite Position Values the BASIC portion of the IRQ interrupt. This will disable most
BASIC sprite and sound commands, but that shouldn't be a
problem for machine language programmers. To prevent exe-
cution of the BASIC IRQ routine, you can either set bit 0 of
the initialization status flag at 2564/$0A04 to %0 (which tells
the Kernal that BASIC is not initialized), or you can store any
nonzero value in the BASIC IRQ status flag at 4861/S12FD.
ates hidden scan lines at the top and bottom of the screen that editor IRQ routine [$C194] sets this bit according to the screen
can be scrolled onto the visible area. mode flag (location 216/$D8). To change the setting of this
Bit 3: This bit determines the vertical height of the active por- bit, you can either store the appropriate value in the flag loca-
tion of the screen display. Setting this bit to %1 selects a 25- tion, or you can disable the screen-setup portion of the IRQ
row (200 scan-line) active screen. The bit is initialized to this routine and change this bit directly. To use the flag location,
setting during the IOINIT routine [$E109], and neither the op- set bit 5 of location 216/$D8 to the desired setting (%0 or %1)
erating system nor BASIC changes this value. Setting this bit for the register bit. To turn off the screen-setup portion of the
to %0 reduces the height of the active portion of the display interrupt routine, store the value 255/SFF in location 216/$D8.
to 24 rows (192 scan lines) by blanking the top four and bot- Bit 6: This bit controls extended background color mode,
tom four scan lines of the display. The pixels in the blanked which offers a choice of four different background colors for
columns aren't erased; they'll still be intact when the screen is each character position. For details about this mode, refer to
switched back to 25 rows. The 24-row feature is useful in con- the introduction for this section. Extended background color
junction with the vertical scrolling feature described in bits 0-2. mode is enabled when this bit is set to % 1 . The mode works
Bit 4: This bit enables or disables the VIC screen display. only in conjunction with character mode. You should not se-
While the bit is % 1 , the VIC provides its normal screen out- lect extended background color mode while bit 5 is set to %1
put. The bit is initialized to this setting during the IOINIT rou- to select bitmapped mode.
tine [$E109]. When the bit is set to %0, the VIC suspends the Bit 7: This bit is effectively the ninth bit of the raster register
active portion of the display and provides a solid screen in the at 53266/$D011. Refer to the discussion of that register for
border color specified in the register at 53280/$D020. The details. The extra bit is necessary because a full screen con-
screen is not erased, just blanked. Any text or graphics will tains more than 256 scan lines.
still be intact if the screen is again enabled. With the display
blanked, the VIC doesn't have to steal timing cycles from the 53266 $D012 RASTER
processor as it normally does. As a result, the 128 actually Raster compare register
runs about 7 percent faster with the VIC display off. This register has two different functions, depending on
There are several uses for this blanking feature. For ex- whether it is being read from or written to. As explained in
ample, you could blank the display while drawing a complex the introduction for this section, the video screen display con-
bitmapped graphics screen, then dramatically unveil the com- sists of a stack of thin horizontal lines of dots called a raster.
pleted picture by reenabling the display. Since the VIC cannot When the register is read, the value returned is the number of
provide a proper display at the 2-MHz clock rate, the VIC dis- the raster scan line currently being drawn. The range of scan-
play is normally blanked when the system is switched to fast line numbers depends on the video system in use. For NTSC
mode. One step in the BASIC statement FAST involves setting (North American) systems, values can be in the range 0-262,
this bit to %0. The SLOW statement returns it to % 1 . This bit while PAL (European) systems have a maximum count of over
is also set to %0 to blank the screen during tape operations, 300. In either case, the active portion of the screen consists of
and restored to %1 upon completion of the operations. scan lines 50-249.
Bit 5: This bit selects whether the VDC will generate a charac- The maximum scan-line number in either system is larger
ter mode display or a bitmapped mode display. (See the intro- than can be held in a single eight-bit register, so bit 7 of the
duction to this section for a discussion of the display modes.) register at 53265/$D011 is used to hold the ninth bit of the
Setting this bit to %0 selects character mode, while setting it value. When bit 7 of 53265/$D011 is % 1 , you should add
to %1 selects bitmapped mode. 256/ $100 to the value in this register to get the true scan-line
This bit cannot be directly modified while the normal sys- number. For scan line 262, for example, bit 7 of 53265/$D011
tem interrupt sequence is active because a step in the screen will be %1 and the value in this register will be 6/$06. Be-
356 357
53267 $D013 $D014 53268
cause the value in this register changes so rapidly (over 15,000 scan line are latched into these registers. The register at
times per second), it can't be read usefully from BASIC. By the 53267/SD013 will hold the horizontal position value, and the
time you PEEKed the value into a variable, the raster scan line one at 53268/$D014 will hold the vertical position value. To
would have moved far beyond the line recorded in the vari- signal that a new value has been latched, bits 7 and 3 of the
able value. interrupt register at 53273/SD019 will be set to % 1 . These
When you write to this register or to bit 7 of 53265/ registers are read-only; writing to them has no effect. The reg-
$D011, the value written is stored in an internal nine-bit raster isters are not cleared when read; the latched values will be re-
compare latch register. Whenever the current scan-line count tained until the LP line is again brought low.
equals the value in this register, bit 0 of the interrupt register The range of scan-line values in the register at 53268/
at 53273/$D019 will be set to % 1 . If bit 0 of the interrupt $D014 is the same as the range of sprite vertical positions
mask register at 53274/$D01A was previously set to % 1 , this shown in Figure 8-6. For example, the top scan line of the ac-
will also trigger an external interrupt request to the processor. tive screen area is 50, In that figure, you'll note that the range
The value you store in this register represents the scan line at of horizontal positions extends to 343, which is greater than
which you wish the interrupt to occur. For scan-line values can be represented in a single eight-bit register. To compen-
less than 256, you must also set bit 7 of 53265/$D011 to %0. sate, the range of horizontal values in the register at 53267/
For scan-line values of 256 or greater, you must set bit 7 of $D013 is the equivalent of one-half the range of horizontal
53265/$D011 to %1 and store the line number minus 256 in values shown in Figure 8-6. For example, the horizontal-position
this register. To calculate the top scan line corresponding to value for the center of the screen is 184, so the corresponding
any row of character positions, use the following formula: light pen position will be about 92.
scan line = (row * 8) + 50 The LP line is connected to pin 6 of control port 1 (con-
where the row value is in the range 0-24. trol port 2 does not support a light pen). A light pen has at its
Raster interrupts can be used to program a variety of spe- tip an electronic device known as a phototransistor, which is
cial video effects, including split screens like those in the connected so as to cause a low pulse whenever the video
GRAPHIC 2 and GRAPHIC 4 modes. The 128 also uses a ras- beam moves past the pen. These registers can be tricked into
ter interrupt off the visible screen (at scan line 255) to drive reading false values. Pin 6 of control port 1 is also used for
the system IRQ sequence. Because of this, you cannot write a light pen input for the VDC chip, so a light pen signal gener-
new value directly to this register while the the normal system ated on the 80-column screen will latch meaningless values in
interrupt sequence is in use. The screen-setup portion of the these registers. In lieu of a light pen, several other events can
screen editor IRQ routine [$C194] will write the value 255/$FF cause a pulse on the LP line. That control port pin is also used
to this register on every pass, except when setting up the bit- for the joystick fire button, so pressing the button of a joystick
plugged into port 1 will also latch values in these registers. Be-
mapped portion of a split bitmapped/text screen. In that case, cause of this joystick button function, the port line is also con-
the value in location 2612/$0A34 will be copied into the reg- nected to the line from row 4 of the keyboard matrix. This has
ister. In either case, bit 7 of the register at 53265/$D011 will two consequences. First, pressing any of the following keys
be set to %0. To use a raster interrupt for your own purposes, with no light pen connected will latch meaningless values: Fl,
you must write a new interrupt routine. Refer to Appendix A Z, C, B, M, period, right SHIFT, space, the 2 and ENTER keys
for more information. on the numeric keypad, and the ^ key in the cursor group.
More significantly, while a light pen is connected, all of these
53267 $D013 LPENX keys will be "dead," and cannot be typed.
53268 SD014 LPENY
Light pen horizontal and vertical positions
Whenever the VIC's LP input line is brought to a low (0 volts)
state, the raster beam's horizontal dot position and vertical
358 359
53269 $D015 $D016 53270
53269 $D015 SPENA screen. Pixels scrolled off the right are not erased, just hidden.
Sprite enable register They will become visible again if the display is scrolled back
This register controls which sprites are enabled. Only enabled to the left by reducing the value in these bits. The 38-column
sprites can be visible, and only enabled sprites can be in- feature is useful with scrolling because it creates a hidden left
volved in collisions. Setting a bit in this register to %1 enables column that can hold pixels to be scrolled onto the visible area.
the corresponding sprite. However, an enabled sprite won't be Bit 3: This bit determines the horizontal width of the screen.
visible unless it is also positioned within the visible screen Setting this bit to %1 selects a 40-column (320-pixel) screen.
area, has a pattern definition that includes some nonzero bits, The bit is initialized to this setting during the IOINIT routine
and is set to a color different from the screen background [$E109], and neither the operating system nor BASIC ever
color. Setting a bit in this register to %0 turns off the cor- change this value. Changing this bit to %0 reduces the width
responding sprite, but does not change the setting of any other of the active portion of the display to 38 columns (304 pixels)
parameters. When reenabled, the sprite will still have the by blanking the leftmost and rightmost columns. (Actually, 7
same position, color, and pattern (unless those were changed pixels on the left and 9 on the right are blanked.) The contents
while the sprite was turned off). The sprites are controlled as of the blanked columns aren't erased; they'll still be intact
follows: when the screen is switched back to 40 columns. The 38-column
Bit Bit value Sprite controlled feature is useful in conjunction with the horizontal scrolling
0 l/$01 ' 0 feature in bits 0-2. Scrolling the 38-column screen the maxi-
1 2/$02 1 mum 7 pixels to the right will make the contents of the previ-
2 4/$04 2 ously hidden leftmost column visible.
3 8/$08 3
4 16/S10 4 Bit 4: This bit controls multicolor mode for both the character
5 32/$20 5 and bitmapped screens. While this bit is %0, foreground pixels
6 64/$40 6 will be limited to one color (although the color can be differ-
7 128/$80 7 ent for every character position). Setting this bit to %1 enables
multicolor mode, which allows a choice of three different col-
This register is initialized to 0/$00 (all sprites disabled) by ors for each foreground pixel. However, selecting multicolor
the IOINIT routine [$E109], part of the reset and RUN/ mode also cuts horizontal resolution for the screen in half. Se-
STOP-RESTORE sequences. Sprites are normally disabled lecting multicolor mode for the screen has no effect on any
during tape and serial bus operations to prevent timing prob- sprites that might be displayed on that screen. Sprite multi-
lems. In this case, the contents of the register are stored in lo- color mode is controlled by the register at 53276/$D01C.
cation 2616/$0A38 for the duration of the operation, then
restored to the register when the operation is completed. You This bit cannot be directly modified while the normal sys-
can prevent this and keep sprites enabled by setting bit 7 of tem interrupt sequence is active because a step in the screen
the custom mode flag (2618/$0A3A) to % 1 . editor IRQ routine [$C194] sets this bit according to the screen
mode flag (location 216/$D8). To change the setting of this bit
for bitmapped mode, you can either store the appropriate
53270 $D016 SCROLX value in the flag location, or you can disable the screen-setup
Horizontal smooth scrolling and control register
portion of the IRQ routine and change this bit directly. To use
Bits 0-2: These bits control the VIC's horizontal smooth scroll- the flag location, set bit 7 of location 216/$D8 to the desired
ing feature. The value here specifies the number of pixels the setting (%0 or %1) for the register bit. To turn off the screen-
display is to be shifted to the right. The available three bits setup portion of the interrupt routine, store the value 255/$FF
allow the screen to be shifted as many as seven pixels. The in location 216/SD8. To select multicolor character mode, you
display scrolls without wrapping; blank pixels are moved in must use the option to disable the screen setup, since the text
from the left and pixels on the right move off the visible mode-setup subroutine always sets this bit to %0.
361
53271 $D017 SD018 53272
Bit 5: This bit is referred to in Commodore literature as the re- setup portion of the screen editor IRQ routine to gain direct
set bit, but its intended usage is unclear. The value here has access to the register. To disable the screen-setup step, store
no apparent affect on any VIC operations. the value 255/$FF in location 216/$D8.
Bits 6-7: These bits are unused. Writing to them has no effect, Bit 0: This bit is unused. Writing to it has no effect, and it
and they always return %1 when read. always returns %1 when read. Thus, the value read from this
register will always be odd.
53271 $D017 YXPAND Bits 1-3: The value in these bits determines the location of char-
Sprite vertical expansion register acter memory (for character mode) or of the bitmap (for bit-
Each bit in this register controls the vertical expansion feature mapped modes). For character mode, a complete 256-character
for one of the eight sprites. The relationship of sprites to regis- set requires 2048 (2K) bytes, and the character set must start
ter bits is the same as for the sprite enable register (53269/ on an even 2K memory address boundary. Possible selections
$D015). Setting a bit here to %1 will double the vertical are as follows:
height of the corresponding sprite. Each sprite can be ex- Bits Offset for
panded independently, with regard for the background screen 3 2 1 character set
on which the sprite is displayed. The resolution of the sprite is 0 0 0 0/$00
not increased—it will still be 21 pixels tall—but the height of 0 0 1 2048/$0800
the pixels will be doubled. Vertical expansion can be selected 0 1 0 4096/$1000
in conjunction with horizontal expansion to double the size of 0 1 1 6144/$1800
a sprite. (Horizontal expansion is controlled by the register at 1 0 0 8192/$2000
53277/SD01D.) The default value in this register, established 1 0 1 10240/$2800
by the IOINIT routine [$E109], is 0/$00, so no sprites are ini- 1 1 0 12288/$3000
tially expanded. 1 1 1 14336/S3800
These bits do not determine the absolute address of the char-
53272 $D018 VMCSB acter set, but rather the offset from the starting address of the
Screen and character base address register current video bank. For example, video bank 2 begins at ad-
The value in this register determines the location within the dress 32768/$8000, so a bit setting of %100 in that case
current 16K VIC video bank of the two movable components would place the character set at 32768 + 8192 = 40960/$A000.
of video memory: the screen memory/video matrix and char- However, the default video bank (bank 0) begins at location
acter memory/bitmap areas. (There is no provision for moving 0/$0000, so in that case the offset is equal to the actual address.
color memory; that area always appears at 55296-56319/ The 128 normally provides a pair of character sets and al-
$D800-$DBFF.) The contents of this register cannot be changed lows you to switch between them by pressing the SHIFT -
directly while the normal system IRQ interrupt sequence is in Commodore key combination. If you are setting up a single
use. The screen editor IRQ routine [$C194] copies the contents custom character set, you should disable this character
of a shadow location into this register during each interrupt. set-switching feature by setting bit 7 of location 247/$F7 to
The shadow location depends on the screen mode in use. For % 1. If you wish to retain the character set-switching feature,
text mode, or for the text portion of a split screen, the contents you must provide two character sets, one at an "even" posi-
of location 2604/$0A2C will be copied here. For bitmapped tion (one for which bit 1 of this register is %0), and the other
modes, the value in location 2605/S0A2D will be copied into at the next higher ("odd") position.
the register. You have two choices for changing the value in The CINT screen editor initialization routine [$C07B] sets
this register. You can either store the desired value in the ap- bits 1-3 to %010 in location 2604/$0A2C, the shadow for this
propriate shadow location, or you can turn off the screen- register in text mode. This places the default character memory
at an offset of 4096/$1000 from the starting address of the
362 363
53272 $D018 SD018 53272
video bank (and implies that the alternate character set will be be protected from BASIC, and any character memory slot in
located at an offset of 6144/$1800), This may seem strange, that area can be used to hold the new character set.
since there is certainly no character pattern data stored in Since the bitmap for a high-resolution display requires
RAM at addresses 4096-8191/$1000-$lFFF/ and since the 8000 bytes of memory and must begin at an even 8K memory
128's memory map shows that the character ROM is actually address boundary, there are only two possible positions for
located at addresses 53248-57343/$D000-$DFFF. However, the bitmap within the 16K video bank. When you are specify-
the 128 has the capability to make the VIC chip see character ing the location of the bitmap, only the setting of bit 3 is sig-
ROM at addresses 4096-6143/$1000-$17FF (for the uppercase/ nificant. When that bit is %0, the bitmap will begin at an
graphics set) and addresses 6144-8191/$1800-$lFFF (for the offset of 0/$0000 from the start of the video bank. When bit 3
lowercase/uppercase set) in any video bank. (Note that this is is % 1 , the bitmap begins at an offset of 8192/$2000 from the
a change from the Commodore 64, which could only see char- start of the video bank. The CINT screen editor initialization
acter ROM in video banks 0 and 2.) Only the VIC will see the routine [$C07B] sets bits 1-3 to %100 in location 2605/$0A2D,
character ROM at those addresses. To the processor, those lo- the shadow for this register in bitmapped mode, so the default
cations will still be RAM. location of the bitmap is 8192/$2000 bytes beyond the start of
This feature is controlled by bit 2 of the 8502's built-in the video bank (address 8192/$2000 for the default video bank).
I/O port, at location l/$01. When bit 2 of the register at
l/$01 is %0, the VIC chip will see character ROM in the char- Bits 4-7: These bits determine the location of the video matrix
acter memory areas beginning at addresses 4096/$1000 and area, which is used as screen memory in character mode and
6144/$1800. No other character memory slots are affected. to hold color information in bitmapped mode. The video ma-
When the I/O port bit is set to % 1 , the VIC will instead see trix requires 1000 bytes of memory and must start on an even
the true contents of RAM at those addresses rather than im- IK address boundary. Possible selections are as follows:
ages of the character ROM. Like other screen control locations, Bits Offset for
the I/O port bit has a shadow location. Bit 2 of location 7 6 5 4 video matrix
217/SD9 is copied into bit 2 of location l/$01 during each 0 0 0 0 0/$0000
pass through the text screen-setup portion of the screen editor 0 0 0 1 1024/$0400
IRQ routine. To switch out character ROM, you must set bit 2 0 0 10 2048/$0800
of the shadow location to %1 (store the value 4/$04 in loca- 0 0 11 3072/$OC00
tion 217/$D9). Alternatively, you can disable the screen-setup 0 10 0 4096/$1000
portion of the screen editor IRQ routine by storing the value 0 10 1 5120/$1400
0 1 1 0 6144/$1800
255/$FF in location 216/$D8; then you change bit 2 of loca- 0 1 1 1 7168/$1COO
tion l/$01 directly. 10 0 0 8192/$2000
Finding free space for a custom character set can be a chal- 0 0 1 9216/$2400
lenge. If you are using machine language exclusively, any of 0 1 0 10240/$2800
the character set slots above address 4864/$1300 can be used, 0 1 1 11264/$2C00
but none of the address slots are completely free in the stan- 1 0 0 12288/$3000
dard configuration with BASIC. If you disable character ROM, 1 0 1 13312/$3400
there is free memory at 6144-7167/$ 18OO-$1BFF for half a char- 1 1 0 14336/S3800
acter set (128 character patterns). If your program doesn't use 1 1 1 15360/$3CO0
a bitmapped screen, you can allocate a bitmap area and then These bits do not determine the absolute address of the video
use the reserved space for custom character sets. For example, matrix, but rather the offset from the starting address of the
if your BASIC program includes the statements GRAPHIC current video bank. For example, video bank 3 begins at ad-
1:GRAPHIC 0, the area from 7168-16383/ $1COO-$3FFF will dress 49152/$C000, so a bit setting of %0010 in that case
would place the character set at 49152 + 2048 = 51200/
364 365
53273 $D019 $D01A 53274
$C800. However, the default video bank (bank 0) begins at lo- quest for the event. Once a bit here is set to % 1 , it will retain
cation 0/$0000, so in that case the offset is equal to the actual that value until the register is read, at which time all func-
address. tional bits are reset to %0.
The C1NT screen editor initialization routine [$C07B] sets Bit 0: This bit will be set to %1 whenever the raster scan-line
bits 4-7 to %0001 in location 2604/$0A2C, the shadow for count equals the value in the raster compare register 53266/
this register in text mode. This places the default character $D012 (plus bit 7 of 53265/$D011).
memory at an offset of 1024/$0400 from the starting address
of the video bank. You can't change this register directly while Bit 1: This bit will be set to %1 whenever a nontransparent
the normal system interrupt sequence is active. To move the portion of a sprite overlaps any screen foreground pixels. (Re-
video matrix for the text screen, you can either change the member, however, that for multicolor character or multicolor
value in location 2604/$0A2C, or you can turn off the screen- bitmapped screens, no collision can be detected between
setup portion of the interrupt sequence by storing the value sprites and foreground pixels represented by %01 bit patterns.)
255/$FF in location 216/$D8. After that, you can change the The register at 53279/$D01F records which sprites are in-
register directly. Even if you change the value in this register, volved in collisions with foreground data.
all printed characters will continue to go to the former screen Bit 2: This bit will be set to %1 whenever two or more sprites
memory range until you change the value in location 2619/ overlap. Collisions can only be detected between the fore-
$0A3B to reflect the new starting page for screen memory. ground portion of the sprites, those pixels represented by non-
Because the bitmap for a high-resolution display requires zero bit patterns. No collision is detected when the over-
half of the memory available in a 16K video bank, only half of lapping portions of the sprites are transparent (when the pixels
the possible addresses are really useful. When setting up a bit- are represented by %0 or %00 bit patterns). The register at lo-
mapped display, you should select a video matrix area in the cation 53278/$D01E records which sprites are involved in col-
portion of the video bank not occupied by the bitmap. The lisions with other sprites.
CINT screen editor initialization routine [$C07B] sets bits 4-7 Bit 3: This bit will be set to %1 whenever a new value is
to %0111 in location 2605/$0A2D, the shadow for this regis- latched into the light pen registers at 53267-53268/
ter in bitmapped mode, so the default location of the video $D013-$D014.
matrix in that mode is 7168/$1COO bytes from the start of the
video bank (address 7168/$1COO for the default video bank). Bits 4-6: The bits are not used, and always return %1 when
Thus, the bitmapped mode video matrix will not disturb char- read.
acter mode screen memory. Bit 7: Whenever any internal interrupt source sets one of the
To move the video matrix for the bitmapped screen, you other bits in this register to % 1 , this bit will also be set to %1
can either change the value in location 2605/$0A2D, or you to indicate that an internal interrupt has been recorded. Thus,
can turn off the screen-setup portion of the interrupt sequence you need to test only this bit to determine whether an internal
by storing the value 255/$FF in location 216/SD8. After that, interrupt has occurred. Note that this register is automatically
you can change the register directly. cleared after it is read, so you'll need to save the register value
before testing this bit if you want to be able to subsequently
53273 $D019 VICIRQ read any of the other bits.
Interrupt register
This register is read-only; writing to this location has no effect. 53274 $D01A IRQMSK
Bits 0-3 indicate the status of the four interrupt sources for the Interrupt enable register
VIC chip. These bits will always reflect the status of their cor- Certain events such as sprite-sprite collisions always generate
responding events, regardless of whether or not register internal VIC interrupts, recorded in the register at 53273/
53274/$D01A has been set to trigger an external interrupt re-
366 367
SD01B $D01D 53277
53275
$D019. The VIC chip has the capability to generate an exter- ground color on the text or bitmapped screens. When a bit
nal interrupt request to the processor as a result of any of here is set to % 1 , the corresponding sprite will have lower pri-
these conditions. In the 128, the VIC's interrupt request output ority than the screen foreground, and will thus appear to pass
line is connected to the processor's IRQ line, so internal VIC behind anything displayed in the foreground color. For multi-
events can trigger processor IRQ interrupts. See Appendix A color character or multicolor bitmapped screen modes, the
for more information on IRQ interrupts. low-priority sprite will appear to pass behind screen pixels
Bit 0: Setting this bit to %1 enables an external interrupt re- represented by %10 and %11 bit patterns, but will still pass in
quest when the raster count match is recorded in the flag at front of pixels represented by %01 bit patterns. (The sprite al-
bit 0 of the register at 53273/$D019. Because raster interrupts ways appears in front of pixels with the %00 background bit
are the normal source of the system jiffy interrupt that drives pattern.) The default value for this register, established by the
keyboard scanning and other important housekeeping fea- IOINIT routine [$E109], is 0/$00, so all sprites initially have
tures, this bit is initialized to %1 by the Kernal IOINIT routine higher priority than the screen foreground.
[$E109]. Changing this bit to %0 will completely disable the
system interrupt. 53276 8D01C SPMC
Sprite multicolor mode register
Bit 1: Setting this bit to %1 enables an external interrupt re-
Each bit in this register controls the multicolor feature for one
quest when a sprite-foreground collision is recorded in the flag
of the eight sprites. The relationship of sprites to register bits
at bit 1 of the register at 53273/$D019, as when a sprite
is the same as for the sprite enable register (53269/$D015).
passes over a character on the text screen.
Setting a bit here to %1 selects multicolor mode for the cor-
Bit 2: Setting this bit to %1 enables an external interrupt re- responding sprite. Multicolor mode can be selected indepen-
quest when a sprite-sprite collision is recorded in the flag at dently for each sprite, and standard and multicolor sprites can
bit 2 of the register at 53273/$D019. be mixed freely on the same screen. Multicolor sprites are not
Bit 3: Setting this bit to %1 enables an external interrupt re- restricted to multicolor screen modes; they can be used freely
quest when a new value is recorded in the flag at bit 3 of the in standard screen modes as well. The default value for this
register at 53273/$D019. It is risky to use this interrupt register, established during the IOINIT routine [$E109], is
source, because a number of events other than the light pen 0/$00, so no sprites are initially in multicolor mode.
can trigger the latching of values into these registers. See the Selecting multicolor mode for a sprite reduces the number
entry for the light pen registers for details. of horizontal pixels for the sprite from 24 to 12. However, the
sprite remains the same size; the multicolor sprite pixels are
Bits 4-7: These bits are unused; writing to them has no effect,
twice as wide. Two bits of the pattern definition are required
and they always return %1 when read. Thus, the value seen
for each pixel. All pixels represented by %00 are transparent;
when this register is read will always be at least 240/$F0. To
whatever is behind the sprite will show through. Pixels with
mask off these unused bits and see the valid interrupt settings,
%01 and %11 bit patterns take their color values from the reg-
use AND 15 in BASIC or AND #$0F in machine language.
isters at 53285/$D025 and 53286/$D026, respectively, which
are common to all multicolor sprites. Pixels with %10 bit pat-
53275 8D01B SPBGPR terns take the color specified in the color register for the par-
Sprite-to-foreground priority register ticular sprite (53287-53294/$D027-$D02E).
Each bit in this register controls the sprite-to-foreground prior-
ity for one of the eight sprites. The relationship of sprites to 53277 $D01D XXPAND
bits is the same as for the sprite enable register (53269/ Sprite horizontal expansion register
$D015). While a bit here is %0, the corresponding sprite will Each bit in this register controls the horizontal expansion fea-
have higher priority than the screen foreground, and will thus ture for one of the eight sprites. The relationship of sprites to
appear to pass in front of anything displayed in the fore-
368
369
53278 $D01E $D020 53280
register bits is the same as for the sprite enable register from the object. Also, sprite-sprite collisions can occur even
(53269/$D015). Setting a bit here to %1 will double the hori- when the sprites are located completely outside the visible
zontal width of the corresponding sprite. Each sprite can be screen area.
expanded independently, without regard for the background
screen on which the sprite is displayed. The resolution of the 53279 $D01F SPFGCL
sprite is not increased (it will still be 24 pixels wide) but the Sprite-foreground collision register
width of the pixels will be doubled. Horizontal expansion can This register records collisions between sprites and the screen
be selected in conjunction with vertical expansion to double foreground. This register is read-only; storing values here has
the size of a sprite. (Vertical expansion is controlled by the no effect. A collision occurs whenever any pixel in a sprite
register at 53271/$D017.) The default value in this register, represented by a nonzero bit pattern overlaps any foreground
established by the IOINIT routine [$E109], is 0/$00, so no pixel on the screen, as when a sprite passes over a character
sprites are initially expanded. on the text screen. Background or transparent pixels are not
involved in collisions. For the purposes of collision detection,
53278 8D01E SPSPCL multicolor screen pixels represented by %01 bit patterns are
not considered foreground, and no collision will be detected
Sprite-to-sprite collision register
when a sprite pixel overlaps a multicolor screen %01 pixel.
This register records collisions between two or more sprites. When a sprite collides with a foreground pixel, the bit in this
This register is read-only; storing values here has no effect. A register corresponding to that sprite is set to %1 (the cor-
collision occurs whenever any nontransparent portions of the respondence between sprites and bits is the same as for the
sprites overlap. Transparent pixels (pixels with bit patterns of sprite enable register). The register is automatically cleared to
%0 or %00) are not involved in collisions. When sprites col- 0/$00 after each time it is read, so you'll need to store the
lide, the bits in this register corresponding to those sprites are value you read if you wish to perform multiple tests. Bit 1 of
set to %1 (the correspondence between sprites and bits is the the interrupt register at 53273/$D019 will also be set to %1
same as for the sprite enable register). Since a minimum of whenever any sprite-foreground collision occurs.
two sprites are involved in any sprite-sprite collision, at least
This register indicates only that a sprite has collided with
two bits will be set. The register is automatically cleared to
some portion of the screen foreground. It does not tell you ex-
0/$00 after each time it is read, so you'll need to store the
actly what the sprite is overlapping. To determine that, you
value you read if you wish to perform multiple tests. Bit 2 of must determine which sprite or sprites are involved in colli-
the interrupt register at 53273/$D019 will also be set to %1 sions, then read the horizontal and vertical position registers
whenever any sprite-sprite collision occurs. for the involved sprites and determine what screen-foreground
This register indicates only that sprites have collided. It object is located in that vicinity. Remember that the sprite po-
does not necessarily tell you which sprites are involved in a sition registers return the position of the upper left corner of
particular collision. If only two bits are set, then those sprites the sprite, which may not be the point of the sprite that is col-
obviously must have hit each other. However, if you find that liding with the foreground.
three or more bits are set, you must read the horizontal and
One thing to beware of when reading this register is that
vertical position registers for the involved sprites and deter- after a sprite overlaps a foreground object, the register will
mine which sprites are in contact with each other. Remember continue to record collisions until the sprite is moved away
that the sprite position registers return the position of the up- from the object.
per left corner of the sprite, which may not be the point of the
sprite that is colliding with the foreground. 53280 $D020 EXTCOL
One thing to beware of when reading this register is that Border color register
after a sprite overlaps a foreground object, the register will The value in this register determines the color of the screen
continue to record collisions until the sprite is moved away border, the area of the screen surrounding the active portion
370 371
53281 SD021 $D024 53284
of the display. When the screen is blanked by setting bit 4 of ways return %1 when read. Thus, the value in this register
the register at 53265/$D011 to %0, the entire display area will will always be at least 240/$F0. To mask off these bits and
be filled with the color specified here. Since the VIC can pro- read the true color value you should use AND 15 in BASIC or
duce only 16 different colors, only four bits are required to AND #$0F in machine language. See Table 8-1 for a list of
hold all possible color values. Thus, only bits 0-3 of this loca- standard VIC color values. This register is initialized to
tion hold meaningful values. Bits 4-7 are unused; writing to ll/$0B (dark gray) by the IOINIT routine [$E109], part of
those bits has no effect, and the bits always return % 1 when both the reset and RUN/STOP-RESTORE sequences. From
read. Thus, the value in this register will always be at least BASIC, the value here can be changed using the statement
240/$F0. To mask off these bits and read the true color value COLOR 0,n (where n is the desired BASIC color number;
you should use AND 15 in BASIC or AND #$0F in machine BASIC color numbers are equal to VIC color values plus one.)
language. See Table 8-1 for a list of standard VIC color values.
The default setting for this register, established by the IOINIT 53282 $D022 BGCOL1
routine [$E1O9], is 13/$0D (light green). From BASIC, the 53283 $D023 BGCOL2
value here can be changed using the statement COLOR 4,rc 53284 $D024 BGCOL3
(where n is the desired BASIC color number; BASIC color Background color registers 1-3
numbers are equal to VIC color values plus one). These three registers are used only when multicolor character
mode or extended background color mode is enabled. For
53281 $DO21 BGCOLO multicolor character mode, the value in 53282/SD022 deter-
Background color register 0 mines the color of any pixels in a screen position represented
In standard character mode, the value here determines the by %01 bit pairs in the character pattern, and the value in
color of all pixels in a screen position which are represented 53283/SD023 determines the color of all pixels with %10
by %0 bits in the character pattern. This background color is pairs. Since there is only one set of registers for all screen po-
common to all screen positions. Clearing the screen fills all po- sitions, the colors of pixels with %01 and %10 bit pairs will be
sitions with the screen code for the space character, which has common to all characters on the screen. The color of pixels
a pattern that is all %0 bits. Thus, a cleared screen will be filled with %00 bit pairs is determined by the value in
with the color specified here. The color of pixels with %1 bits in 53281/SD021, and the color of pixels with %11 bit pairs is se-
the character pattern (the foreground color) is determined by lected individually for each character position by the value in
the value in the color memory location for the position. the corresponding color memory location (55296-56319/
This register is also used in both of the other character $D800-$DBFF). The register at 53284/$D024 is unused in mul-
modes. In multicolor character mode, the value here deter- ticolor character mode,
mines the color of all pixels in all screen positions represented For extended background color mode, these registers de-
by %00 bit pairs in the character pattern. In extended back- termine the background color for the character position for the
ground color mode, the value here determines the background character, depending on the setting of bits 6-7 of the screen
color in any screen positions for which bits 6-7 of the screen code in the screen memory location for the position. The se-
code in the corresponding screen memory location are %00. lections are as follows:
This register is unused in standard bitmapped mode, but for Bits Background color source register
multicolor bitmapped mode the value here determines the 7 6
color for all pixels represented in the bitmap by %00 bit pairs. 0 0 53281/SD021
Since the VIC can produce only 16 different colors, only 0 1 53282/$D022
four bits are required to hold all possible color values. Thus, 1 0 53283/$D023
only bits 0-3 of this location hold meaningful values. Bits 4-7 1 1 53284/$D024
are unused; writing to those bits has no effect, and the bits al-
372 373
53235 $D025 SD02E 53294
Since the VIC can produce only 16 different colors, only IOINIT routine [$E109], are 1 (white) for 53285/$D025 and 2
four bits are required to hold all possible color values. Thus, (red) for 53286/$D026. From BASIC, these settings can be
only bits 0-3 of these locations hold meaningful values. Bits changed using the SPRCOLOR statement.
4-7 in any of these locations are unused. Writing to those bits
has no effect, and the bits always return % 1 when read. Thus, 53287 SD027 SPOCOL
the value in any of these locations will always be at least 53288 SD028 SP1COL
240/$F0. To mask off these bits and read the true color value 53289 SD029 SP2COL
you should use AND 15 in BASIC or AND #$0F in machine 53290 $D02A SP3COL
language. See Table 8-1 for a list of standard VIC color values. 53291 8D02B SP4COL
These registers are initialized during the IOINIT routine 53292 $D02C SP5COL
[$E019], part of the reset and RUN/STOP-RE STORE se- 53293 $D02D SP6COL
quences. The default values are 1 (white) for 53282/$D022, 2 53294 $D02E SP7COL
(red) for 53283/$D023, and 3 (cyan) for 53284/$D024. There Sprite color registers
is no BASIC statement specifically for changing the settings of Each of these registers holds color information for one of the
these registers. eight sprites. For standard sprites, the value here determines
the color of all %1 bits in the sprite pattern (%0 bit positions
53285 $D025 SPMCO will be transparent). For multicolor sprites, the value here de-
53286 $D026 SPMC1 termines the color of all %10 bit groups in the pattern.
Sprite multicolor registers Since the VIC can produce only 16 different colors, only
The values in these registers determine two of the colors for four bits are required to hold all possible color values. Thus,
multicolor sprites. (A sprite can be switched to multicolor only bits 0-3 of these locations hold meaningful values. Bits
mode by setting the appropriate bit in the register at 53276/ 4-7 in any of these locations are unused. Writing to those bits
$D01C.) The value in the register at 53285/$D025 determines has no effect, and the bits always return %1 when read. Thus,
the color for all pixels in the sprite represented by %01 bit the value in any of these locations will always be at least
pairs in the pattern. The value in 53286/$D026 determines the 240/$F0. To mask off these bits and read the true color value
color for all pixels represented by %11 bit pairs. Since there you should use AND 15 in BASIC or AND #$0F in machine
are only these two registers for all eight sprites, the colors of language. See Table 8-1 for a list of standard VIC color values.
pixels with %01 and %11 bit pairs will be common to all The following table shows the default colors for each sprite,
sprites. The color of pixels represented by %10 bit pairs can be established by the IOINIT routine [$E109], part of both the re-
selected individually for each sprite using the registers at set and RUN/STOP-RESTORE sequences.
53287-53294/$D027-$D02E. Pixels with %00 bit pairs in the
pattern will be transparent. Register Sprite Default color
Since the VIC can produce only 16 different colors, only 53287/$D027 0 0 (black)
four bits are required to hold all possible color values. Thus, 53288/$D028 1 1 (white)
only bits 0-3 of these locations hold meaningful values. Bits 53289/$D029 2 2 (red)
4-7 in any of these locations are unused. Writing to those bits 53290/$D02A 3 3 (cyan)
has no effect, and the bits always return %1 when read. Thus, 53291/$D02B 4 4 (pmple)
the value in any of these locations will always be at least 53292/$D02C 5 5 (green)
240/$F0. To mask off these bits and read the true color value 53293/$D02D 6 6 (blue)
53294/$D02E 7 7 (yellow)
you should use AND 15 in BASIC or AND #$0F in machine
language. See Table 8-1 for a list of standard VIC color values.
The default settings of these registers, established by the
374 375
53295 $D02F $D031-$D03F 53297-53311
53295 $D02F XSCAN screen becomes a colorful pattern of rapidly flashing squares.
Extended keyboard scan-line control register It is common practice to set bit 4 of the VIC register at 53265/
Bits 0-2: Each of these bits controls the state of one of the $D011 to %0 to blank the 40-column screen display while op-
three output lines from the VIC chip, K0-K2. Setting a register erating in 2-MHz mode. For example, the BASIC routine for
bit to %0 causes the corresponding output line to go to a low the FAST statement [$77B3] includes this step. The VDC pro-
(0 volts) state, while setting a register bit to %1 causes the vides an alternative to the VIC for fast mode, but other I/O
output line to go to a high ( + 5 volts) state. Reading these bits chips have no substitutes. In these cases, the system employs
returns the current state of the corresponding output lines. In an elaborate technique known as clock stretching, where the
the 128, the three output lines are used to scan the three key- clock period is extended to create an effective 1-MHz rate for
board columns containing the 24 keys in the numeric keypad the portion of the clock cycle when the I/O chip is being
and top row of control keys. See Figure 7-1 and the discussion accessed.
of the keyboard scanning routine [$C55D] in Chapter 7 for Because some serial bus and tape communications
more information. routines depend on software loops for timing functions, the
Unless you are writing a custom keyboard scanning rou- system is usually switched to the slower clock frequency when
tine, there's rarely a need to tinker with this register. The out- serial bus or tape operations are being performed. The con-
put lines are connected only to the keyboard, and are not tents of this register are stored in location 2615/$0A37 during
available externally. the operation, and restored to the register when the operation
is completed. You can prevent this by setting bit 7 of the cus-
Bits 3-7: These bits are unused. Writing to them has no effect, tom mode flag (location 2618/$0A3A) to % 1 . In this case, the
and they always return %1 when read. Thus, the value in this clock rate will not be changed during tape and serial
location will always be at least 248/$F8. To mask off these ir- operations.
relevant bits, use AND 7 in BASIC or AND #$07 in machine
language. Bit 1: This bit is described in Commodore literature as a test
bit. The IOINIT routine [$E019] sets the bit to %0, and no
53296 $D030 CLKRATE other 128 ROM routine changes that setting. Some program-
Processor clock rate control register mers have discovered that setting this bit to %1 will blank the
40-column screen display, and have even used this as an alter-
Bit 0: This bit controls the processor clock speed. (Remember, native to clearing bit 4 of location 53265/$D011 when switch-
the VIC chip is the source of most of the system's timing sig- ing the processor to fast mode. While this does appear to work
nals.) When the bit is set to %0, the processor operates at its without side effects, such undocumented "features" are best
normal 1-MHz rate. To be precise, the clock frequency is avoided.
1.02273 MHz for NTSC (North American) systems and 0.98525
MHz for PAL (European) systems. Setting this bit to %1 dou- Bits 2-7: These bits are unused. Writing to them has no effect,
bles the clock rate, providing what is commonly referred to as and they always return %1 when read. Thus, the value in this
2-megahertz (MHz) mode. This is also known as fast mode, register will always be at least 252/$FC. To mask off these
the old standard speed being disparagingly referred to as slow bits, use AND 3 in BASIC or AND #$03 in machine language.
mode. During the reset and RUN/STOP-RESTORE sequences,
the IOINIT routine [$E109] sets this bit to %0 for slow mode. 53297-53311 $D031-$D03F Unused
Fast mode does have a few limitations. While the 8502 These unused register addresses always return the value
microprocessor and the VDC 80-column video chip have no 255/$FF when read. Writing to these locations has no effect.
problems operating at the higher clock rate, most of the other
I/O chips cannot keep up at this speed. The VIC chip itself
cannot maintain its video display at this speed—the 40-column
376 377
53312-54271 $D040-$D3FF $D400-$D41C 54272-54300
53312-54271 $D040-$D3FF
VIC chip register images In the common musical scale, every note is assigned a
particular frequency (see Appendix D). But you don't have to
Due to incomplete address decoding, images of the VIC chip know much about music to know that a C note played on a
registers repeat every 64 bytes through the remainder of this guitar sounds different from one played on a piano or flute or
page of memory. That is, storing a value in any location in
this range which has an address that is an exact multiple of 64 organ. Obviously, there is more to sound than just frequency.
greater than one of the base register locations has the same ef- The next important characteristic is waveform. The sound
fect as storing that same value at the base register location. For wave for a "pure" tone will have a sinusoidal waveform, as
example, storing a value at 53312/$D040 or 54208/$D3C0 shown in Figure 8-7. However, a sine waveform is relatively
has the same effect as storing a value in 53248/$DOOO. How- difficult to synthesize digitally, so it is fortunate that pure
ever, it's better programming practice to use the officially des- tones are relatively rare.
ignated register addresses. Figure 8-7. Sinusoidal Waveform
Figure 8-8. SID Waveforms fundamental frequency plus odd harmonics in diminishing
proportions; the sawtooth waveform, which corresponds to a
fundamental frequency plus both odd and even harmonics in
diminishing proportions; and the pulse waveform, which has a
varying mix of harmonics depending on the width of the
pulse. Figure 8-8 illustrates these waveforms. The triangle
waveform corresponds to mellow sounds like those of the xy-
lophone. The sawtooth waveform corresponds to the slightly
harsher sound of instruments like the guitar or accordion. Be-
cause the harmonic content of the pulse waveform is variable,
it can be used for a variety of sounds ranging from piano to
trumpet.
Note that Figure 8-8 includes a fourth waveform not pre-
viously mentioned. In addition to the "orderly" waveforms,
the SID can also produce a waveform that varies constantly
with no discernible frequency. Such a pattern (or lack of pat-
tern) is characteristic of the class of sounds we call noise. De-
pending on how fast the wave changes levels, it can range
from a low buzz to a high hiss like radio station static.
The final component of sound that can be controlled by
the SID is the envelope. If you visualize the sound waveforms
as shown in Figure 8-8, the volume of the sound corresponds
to the height of the waveform, technically called the ampli-
tude of the wave. While some instruments like the organ can
start a note playing at a constant amplitude (volume) and turn
it off almost immediately, most instruments take a certain
amount of time to bring a note to full amplitude, and in some
instruments a note will linger for a brief period after it has
been played. This rise and fall of amplitude is called the enve-
lope of the waveform, and is usually described in terms of at-
tack, decay, sustain, and release (ADSR), as illustrated in
Figure 8-9, Each class of instrument has a characteristic ADSR
envelope.
The attack is the time required for the note to rise from si-
lence to maximum volume after it is begun—for example, after
a string is picked or bowed or struck. Decay is the time re-
quired for the note to drop from maximum volume to its sus-
tain level, where it remains until it begins to die away to
silence again (the release phase). Not every sound will exhibit
every phase of the ADSR envelope. For example, the envelope
for instruments like the guitar or piano which have plucked or
struck strings will have almost no attack time; the envelope for
380 381
$D400-$D41C 54272-54300
54272-54300 $D400-$D41C
instruments like the flute, where the player must start a col-
umn of air vibrating, have a significant attack time. The dis-
cussion of the ENVELOPE statement in the System Guide that
came with your 128 shows the relative ADSR parameters of a
variety of instrument types. If you are confused about the rela-
tionship between frequency, waveform, and envelope, Figure
8-10 should help clear up some of the confusion.
Table 8-3 lists the available registers of the SID chip. A
detailed description of each follows. The SID's 29 registers fall
into two distinct classes. The first 25 are write-only; reading
from them returns zeros or meaningless values. The final 4 are
read-only; writing to them has no effect. All 128 SID registers
appear in the same locations and have the same functions as
the Commodore 64's SID chip. Thus, any Commodore 64
sound routine should also work in Commodore 128 mode. In
addition to being loaded directly, some of these registers can
also be loaded indirectly from shadow registers as part of the
BASIC IRQ service routine.
383
382
54272 $D400 6D401 54273
T a b l e 8-3. SID Chip R e g i s t e r s clock rate depends on which video system the 128 uses. For
54272/$D400 Frequency register for voice 1 {low byte) NTSC (North American) systems, the clock value is 1022730
54273/$D401 Frequency register for voice 1 (high byte) Hz, while for PAL (European) systems it is 985250 Hz. Thus,
54274/$D402 Pulsewidth for voice 1 (low byte) you can use the following expressions to calculate the fre-
54275/$D403 Pulsewidth for voice 1 {high byte) quency produced by any given register setting:
54276/$D404 Control register for voice 1 frequency = register value * 0.06096 (for NTSC systems)
54277/$D405 Attack/decay register for voice 1 frequency = register value * 0.05873 (for PAL systems)
54278/$D406 Sustain/release register for voice 1
54279/SD407 Frequency register for voice 2 (low byte) Since the register pair can hold values from 0-65535/
54280/$D408 Frequency register for voice 2 (high byte) $0000-$FFFF, the range of possible output frequencies for an
54281/$D409 Pulsewidth for voice 2 {low byte) NTSC system is 0-3995 Hz. A register value of zero corre-
54282/$D40A Pulsewidth for voice 2 {high byte) sponds to no frequency, hence no sound. The upper limit of
54283/$D40B Control register for voice 2 human hearing is about 20,000 Hz, but the fact that the SID
54284/$D40C Attack/decay register for voice 2 can't generate frequencies above 4000 Hz isn't really a serious
54285/$D40D Sustain/release register for voice 2 handicap. The frequencies between 4000 and 20,000 Hz are
54286/$D40E Frequency register for voice 3 (low byte) not often used in music. For example, the highest note on a
54287/$D40F Frequency register for voice 3 (high byte) piano (a C four octaves above middle C) has a frequency of
54288/$D410 Pulsewidth for voice 3 {low byte) 4186 Hz, just slightly beyond the SID's range. The SID can
54289/$D411 Pulsewidth for voice 3 (high byte) produce notes corresponding to those for any of the 88 keys
54290/$D412 Control register for voice 3 on a piano keyboard except the very rightmost one. The lower
54291/$D413 Attack/decay register for voice 3 limit of human hearing is about 20 Hz, so register values less
54292/$D414 Sustain/release register for voice 3 than about 320/$0140 should result in inaudible output re-
54293/SD415 Filter cutoff frequency {low byte)
54294/$D416 Filter cutoff frequency (high byte) gardless of the volume setting. Actually, this is true only for
54295/$D417 Resonance/filter control register the triangle waveform. The sudden transitions in output am-
54296/$D418 Volume/filter mode register plitude during sawtooth and pulse waveforms will produce a
54297/$D419 Potentiometer (paddle) x position clicking or buzzing output at these supposedly inaudible low
54298/$D41A Potentiometer (paddle) y position frequencies.
54299/$D41B Voice 3 oscillator output If you know the frequency (in hertz) that you wish to
54300/$D4lC Voice 3 envelope generator output generate, you can calculate the corresponding register setting
using the following formulae:
54272 $D400 FRELO1 register value = desired frequency * 16.40 (for NTSC systems)
54273 $D401 FREHI1 register value = desired frequency * 17.03 (for PAL systems)
Frequency control registers
The value in this pair of registers determines the frequency of See Appendix D for a list of the standard frequencies for musi-
the sound generated for voice 1. The higher the frequency, the cal notes and the register values required to produce those fre-
higher the pitch of the sound. For triangle, sawtooth, and quencies. It is permissible to change the frequency of a sound
pulse waveforms, the relationship between the value in these while it is playing. The change will take effect immediately,
registers and the voice 1 sound frequency in hertz (cycles per and will not affect the envelope. Changing the frequency of an
second) is: active sound can produce interesting effects. See the entry for
the register at 54299/$D41B for an example.
frequency = register value * clock rate / 16777216 The noise waveform doesn't have a regularly repeating
The first register (54272/$D400) holds the low byte of the pattern like the triangle, sawtooth, and pulse waveforms. The
value and the second (54273/$D401) holds the high byte. The output jumps erratically from one amplitude level to another,
384 385
54274 $D402 $D403 54275
so noise doesn't really have a frequency in the same sense Figure 8-11. Pulse Waveform Duty Cycles
that the other waveforms do. For noise, the value in these reg-
isters determines how rapidly the amplitude level changes.
The number of changes per second is approximately equal to
the register value. For example, a register value of 1000/$03E8
will cause the noise output level to change about 1000 times
per second, or approximately one change every 1/1000 sec-
ond. The faster the output level changes, the higher the per-
ceived pitch of the generated noise.
Remember that these are write-only registers; they will al-
ways return 0/$00 when read, regardless of the values you
have stored in them.
386 387
54275 $D403 $D404 54276
4-7 of 54275/$D403 are unused; any value written to these It is permissible to change the value in these registers, and
bits has no effect. The available 12 bits allow register values of hence the width of a pulse waveform, while the voice is gen-
0-4095/$000-$EFF, Thus, you can specify duty cycles in the erating output. This will affect only the waveform, not the en-
full range 0-100 percent. If you know the duty cycle you velope. Remember that these are write-only registers; they will
want, you can calculate the proper register value with: always return 0/$00 when read, regardless of the values you
register value = (100 — desired duty cycle) * 40.95 have stored in them.
In the expression above, the duty cycle is expressed as a per- 54276 8D404 VCREG1
centage. For example, the required register value for a 50-percent
duty cycle—a square wave—would be (100 — 50) * 40.95 = Voice 1 control register
2048/$0800. For this, you would store the low byte (0/$00) in Each bit of this register controls some aspect of the output
54274/$D402 and the high byte (8/$08) in 54275/$D403. sound for the voice. Remember that this is a write-only regis-
There's one phemomenon you need to be aware of when ter. All of the following bits return %0 when read.
selecting duty cycles. The relative percentage of the pulse Bit 0: This bit, called the gate flag, is used to initiate output for
waveform cycle spent in each state, rather than the actual this voice and to trigger the release portion of the defined
state, determines how the resulting output will sound. Notice sound envelope for the voice. (See the introduction of this sec-
in Figure 8-11 that both the 25-percent and 75-percent duty tion for more information on sound envelopes.) Writing a %1
cycles have waveforms that are in one state for 25 percent of here starts the attack portion of the envelope. This is some-
the cycle and the other state for 75 percent of the cycle. In times referred to as gating the voice. For audible output, the
either case, the ratio of time spent in each state is 3 to 1. A frequency registers for this voice and the overall volume regis-
pulse wave with a 75-percent duty cycle will sound exactly ter for the chip must contain nonzero values. The attack por-
the same as one with a 25-percent duty cycle. For every pulse tion of the envelope will normally be followed by the decay
waveform duty cycle less than 50 percent, there is a duty cycle phase, after which the sound amplitude will remain at the
greater than 50 percent that will produce the same sound. For specified sustain level until a %0 is written to this register.
example, a waveform with a 10-percent duty cycle (on for 10 After the %0 is written, the release phase begins and the
percent of the cycle and off for the remaining 90 percent) will sound output level will fade away to silence at the specified
sound the same as a waveform with a 90-percent duty cycle release rate. (Release does not occur unless a %0 is specifically
(on for 90 percent of the cycle and off for the remaining 10 written to this bit.)
percent), since for either waveform the cycle is divided be- Note that writing a %0 here triggers the release phase re-
tween the two states in a 9-to-l ratio. gardless of the current state of the envelope. For example, if
The closer the register value is to 2048/$0800—the value you write a %1 here and then immediately write a %0 before
for a square wave (50-percent duty cycle, 1-to-l ratio of time the attack phase is completed, the attack will be aborted and
in each state)—the richer the resulting output will sound. As release will begin from the current amplitude level. Likewise,
the register value approaches 4095 or 0, for 0- or 100-percent writing a %1 here initiates the attack phase, regardless of the
duty cycles, respectively, the ratio approaches its maximum of current state of the envelope. For example, if a %1 is written
1 to 4095 and the resulting sound output becomes increasingly here while the envelope for the voice is in the decay phase,
thin. Very low or very high duty cycles result in nearly inau- the decay phase will be aborted and another attack phase will
dible output. Duty cycles of exactly 0 or 100 percent result in begin from the current amplitude level.
constant output levels. Since some variation in the output is Bit 1: This bit, called the sync flag, controls a special effect
required to produce sound, register values of 0/$000 or 4095/ known as synchronization, which changes the frequency of
$FFF produce no audible output. and adds extra harmonics to the voice 1 output. When this bit
is set to % 1 , the waveform of voice 1 will be synchronized
388
54276 $D404 SD404 54276
with the waveform of voice 3. That is, whenever the waveform Ring modulation is rather difficult to explain simply.
of voice 3 starts a new cycle, voice 1 will also start a new cy- When you ring modulate voice 1 at the frequency of voice 3,
cle, regardless of its point in its current waveform. Figure 8-12 the resulting waveform is the equivalent to the sum of two
illustrates the effect on the voice 1 waveform. waveforms of different frequencies. However, the resulting fre-
Figure 8-12. Voice 1 Synchronized with Voice 3 quencies are different from both the frequency of voice 1 and
that of voice 3. Figure 8-13 is an example of one observed
ring-modulated output.
Figure 8-13. Voice 1 Ring Modulated by Voice 3
voice I
voice 1
voice 3
frequency
voice 3
frequency
resulting
output
resulting
output
Only the frequency specified for voice 3 is significant for The ring modulated waveform will have a complex mix of
synchronization. In fact, it doesn't matter whether voice 3 is harmonics. This is useful for simulating the sounds of bells,
turned on or not, so long as a frequency value is stored in the gongs, and similar instruments whose waveforms don't closely
frequency control registers for the voice. (Synchronization has resemble the triangle, sawtooth, or pulse.
no effect if the frequency for the synchronizing voice is zero.) Only the frequency specified for voice 3 is significant for
Ideally, the frequency for voice 3 should be less than that ring modulation, (Voice 1 must be set for a triangle waveform,
specified for voice 1. but the waveform of voice 3 is irrelevant.) It doesn't even mat-
Synchronization also works for voices 2 and 3. Setting ter whether voice 3 is turned on or not, as long as a frequency
this bit in the control register for voice 2 (54283/$D40B) al- value is stored in the frequency control registers for the voice.
lows voice 2 to be synchronized with voice 1, and setting this (Ring modulation has no audible effect if the frequency for the
bit in the control register for voice 3 (54290/$D412) allows modulating voice is zero.)
voice 3 to be synchronized with voice 2. It is possible to have Ring modulation also works for voices 2 and 3. Setting
two or all three voices synchronized simultaneously. this bit in the control register for voice 2 (54283/$D40B) al-
lows voice 2 to be ring modulated by voice 1. (Voice 2 must
Bit 2: This bit, called the ring mod flag, controls a special effect be set for a triangle waveform.) Setting this bit in the control
known as ring modulation. When this bit is set to %1 and a register for voice 3 (54290/$D412) allows voice 3 to be ring
triangle waveform is selected for the voice, the triangle wave- modulated by voice 2, (Voice 3 must be set for a triangle
form will be ring modulated at the frequency of voice 3. (Ring waveform.) It is possible for two or all three voices to be
modulation works only when the triangle waveform is selected.) simultaneously ring modulated.
390 391
54276 SD404 $D405 54277
Bit 3: This bit, called the test flag, can be used to reset the in- 54277 $D405 ATDCY1
ternal oscillator for the voice. When this bit is set to % 1 , the
internal-oscillator register is reset to zero, halting sound output Attack and decay control register
for the voice. The oscillator remains stopped until a %0 is This register controls the behavior of the attack and decay
written to this bit. You can use this bit to precisely control phases of the envelope for the voice.
when the voice oscillator turns off or on. You must also use Bits 0-3: These bits control the decay rate, the amount of time
this bit to unfreeze the noise output if you accidentally turn on required for the voice to drop from the peak amplitude at-
noise while another waveform is active. tained during the attack phase to the specified sustain level.
Bits 4-7: These bits control the behavior of the internal oscil- For decay to have any audible effect, the sustain level must be
lator for the voice, and hence the resulting waveform of the less than %1111/$F. There is no simple formula relating the
sound output for the voice. (See the introduction to this sec- bit value to the corresponding time. The following table shows
tion for more information on waveforms.) Each bit controls the relationship:
one of the standard waveforms, as follows: Bits Value Time required for
32 10 decay phase (in seconds)
Bit Value Waveform
4 16/$10 triangle 00 00 0/$00 0.006
5 32/$20 sawtooth 0 0 01 l/$01 0.024
6 64/$40 pulse 0 0 10 2/$02 0.048
7 128/$80 noise 0 0 11 3/$03 0.072
0 10 0 4/$04 0.114
Setting one of these bits to %1 tells the oscillator to produce 0 10 1 5/$05 0.168
the corresponding waveform. Setting the bit to %0 turns off 0 110 6/$06 0.204
that waveform. One of the waveforms must be selected for the 0 111 7/$07 0.240
voice to produce any output. 10 0 0 8/$08 0.300
Since the waveforms can be independently selected, you 10 0 1 9/$09 0.750
might be tempted to simultaneously enable more than one 10 10 10/$0A 1.50
10 11 11/S0B 2.40
waveform for the voice. This won't hurt the SID chip, but 110 0 12/$0C 3.00
you'll probably be disappointed with the results. When you 110 1 13/$0D 9.00
select more than one waveform, the resulting output is not the 1110 14/$0E 15.0
simple combination of the selected waveforms. Commodore 1111 15/$0F 24.0
literature continues to claim that the result will be a logical You can change the decay rate while a sound is being played.
ANDing of the selected waveforms, but the SID's designer has However, unless the envelope is currently in the attack or de-
stated that this is not the case. In any event, mixed waveforms cay phase, the change won't have any effect until the next
tend to produce a rather erratic sound, so the technique isn't time the envelope is started by writing a %1 to the gate bit for
really useful. Furthermore, you'll cause a problem if one of the the voice (bit 0 of the control register).
waveforms in the combination is noise. When the noise wave-
form is selected while any other waveform is also selected, the Bits 4-7: These bits control the attack rate, the amount of time
noise generator for the voice will cease to function. To restart required for the sound output of the voice to rise from silence
it you'll have to write a %1 and then a %0 to the TEST flag (zero amplitude) to peak amplitude. The attack phase begins
(bit 3 of this register) or reset the computer. when a %1 is written to the gate bit for the voice (bit 0 of the
control register). There is no simple formula relating bit values
to the corresponding attack rates. The following table shows
the relationship. Note that attack rates are three times faster
392 393
54278 SD406 $D406 54278
than corresponding decay or release rates. This is because the Bits Value Time required for
attack phase tends to be shorter than decay or release for most 3210 release phase (in seconds)
naturally occurring sounds. 0000 0/$00 0.006
Bits
000 1 l/$01 0.024
Value Time required for 00 10 2/$02 0.048
7654 attack phase (in seconds)
00 11 3/$03 0.072
0000 0/$00 0.002 4/$04 0.114
000 1 16/$10 0.008 oioo
010 1 5/$05 0.168
00 10 32/$20 0,016 oiio 6/$06 0.204
00 11 48/$30 0.024 0111 7/S07 0.240
0 100 64/$40 0.038 1000 8/$08 0.300
0 10 1 80/$50 0.056 1001 9/$09 0.750
0 110 96/560 0.068 1010 10/$0A 1.50
0 111 112/$70 0.080 10 11 ll/$0B 2.40
1000 128/$80 0.100 1100 12/$0C 3.00
100 1 144/$90 0.250 110 1 13/$0D 9.00
10 10 160/$A0 0.500 1110 14/$0E 15.0
10 11 176/$B0 0.800 1111 15/$0F 24,0
1100 192/$C0 1,00
110 1 208/$D0 3.00 It is possible to change the release rate while a sound is
1110 224/$E0 5.00 being played. The new rate will supersede the old one, even if
1111 240/$F0 8.00 the envelope is currently in the release phase.
Yot i can change the attack rate while a sound is being Bits 4-7: These registers specify the volume level at which the
played. However, unless the envelope is currently in the at- voice output will be maintained during the sustain level of the
tack phase, the change won't have any effect until the next envelope. Note that this is different from the attack, decay,
time the1 gate bit for the voice (bit 0 of the control register) is and release values, which specify periods of time instead of
set to %1 to restart the envelope. levels. Once the attack and decay phases are completed, the
voice will remain at the level specified here until the release 54286 SD40E FRELO3
phase is specifically triggered by writing a %0 to the control 54287 $D40F FREHI3
register for the voice. The sustain level can be considered a Frequency control register
percentage of the peak volume level of the output, as shown 54288 $D410 PWLO3
in the following table. (The overall peak output level is con- 54289 $D411 PWHI3
trolled by bits 0-3 of the register at 54296/$D418.) Pulsewidth control register
If 0 is specified for the sustain level, the voice will die
away to silence at the end of the decay period. You can 54290 $D412 VCREG3
change the value in these bits to reduce the sustain level (and Waveform control register
hence the output volume) while a sound is being played. 54291 $D413 ATDCY3
However, if you try to increase the sustain level above its cur- Attack and decay control register
rent value while a voice is in the sustain phase, the voice will 54292 $D414 SUREL3
be turned off.
Sustain and release control register
Voice 2 Control Registers 54293 $D415 FCLO
The following seven registers (54279-54285/$D407-$D40D) 54294 SD416 FCHI
provide the same control functions for voice 2 that the regis- Filter cutoff frequency registers
ters at 54272-54278/$D400-$D406 provide for voice 1. Refer
to the entries for the voice 1 registers for details of how these The value in these registers specifies the cutoff frequency for
registers are used. the filter. See the entry for bits 4-6 of the register at
54296/$D418 for more information on the effect of filtering.
54279 $D407 FRELO2 Only 11 of the 16 bits in this register pair are used. The lower
54280 $D408 FREHI2 3 bits of the value come from bits 0-2 of the register at
Frequency control registers 54293/SD415 and the upper 8 bits come from the register at
54281 $D409 PWLO2 54294/$D416. Bits 3-7 of 54293/$D415 are not used, and
54282 $D40A PWHI2 writing to those bits has no effect. Remember that these are
Pulsewidth control registers write-only registers; they will always return 0/$00 when read,
regardless of the values you have stored in them.
54283 $D40B VCREG2 The available 11 bits allow you to specify values in the
Waveform control register range 0-2047/$0000-$07FF. However, there is a great deal of
54284 $D40C ATDCY2 confusion about the exact relationship between the value in
Attack and decay control register these registers and the corresponding cutoff frequency. Sup-
54285 $D40D SUREL2 posedly, the value here specifies the cutoff frequency in linear
Sustain and release control register steps between a minimum of about 30 Hz and a maximum de-
termined by two external capacitors connected to the SID chip.
Voice 3 Control Registers Commodore's formal specifications for the SID chip state that
The following seven registers (54286-54292/$D40E-$D414) the equation for maximum cutoff frequency is:
provide the same control functions for voice 3 that the regis- frequency = 2.6 X 10"5 / capacitance
ters at 54272-54278/$D400-$D406 provide for voice 1. Refer Other official literature, including the 128 Programmer's Refer-
to the entries for the voice 1 registers for details of how these ence Guide, states that the maximum cutoff frequency is about
registers are used. 12,000 Hz, a calculation based on filtering capacitors of 2200
picofarads (2200 X 10"12). There are a number of problems
396 397
54295 $D417 $D41S 54296
here. First of all, the capacitors used in the 128 (and, by the Bit 2: This bit provides the same filter control function for
way, also in later versions of the Commodore 64) are instead voice 3 that bit 0 provides for voice 1.
actually 470 picofarads, not 2200, If the stated equations were
correct, this would give a maximum cutoff value of over Bit 3: This bit controls the handling of any external audio in-
55,000 Hz, implying that the majority of register values would put to the SID. As with bits 0-3, setting this bit to %0 con-
produce cutoff frequencies beyond the audible range. Simple nects the external input directly to the combined output, while
experimentation shows that this is not the case. This isn't sur- setting the bit to %1 routes the external input through the fil-
prising, since the SID's designer, Bob Yannes, stated in an in- ter before output. These two functions—adding directly to the
terview in the March 1985 issue of IEEE Spectrum magazine output or adding to the filtered output—are the only process-
that filtering doesn't work according to the specified equation ing the SID can perform on the input signal from an external
anyway. source. The SID's external input line is connected to pin 5 of
So how do you go about selecting a cutoff frequency? Our the composite (40-column) video port. To avoid damage to the
experience suggests that, while filtering does work after a SID, you should not use highly amplified signals such as the
fashion for any given 128, a value that produces a particular final output of a home stereo system for the external input
cutoff frequency on one computer may produce a slightly dif- source.
ferent cutoff frequency on another system. Although it's not a Bits 4-7: These bits control an effect of filtering known as res-
particularly scientific approach, the best way to discover the onance. The four bits provide for 16 evenly spaced steps from
proper register value for a given cutoff frequency is simply to no resonance (%0000) to full resonance (%1111). Resonance
try different values until the desired effect is achieved. accentuates frequencies near the cutoff frequency for the filter.
The higher the resonance, the more pronounced the effect of
54295 $D417 RES/FILT the selected filter.
Filter selection and resonance control register
The bits of this chip select whether the various audio sources 54296 $D418 SIGVOL
in the SID will be passed directly to the chip output or routed Volume and filter mode control register
through the filter stage. This register also controls a special fil- This register controls the overall volume of the SID output, as
tering effect known as resonance. Remember that this register well as the type of frequency attenuation provided by the fil-
is write-only; all bits will return %0 when read, regardless of ter. Remember that this register is write-only; reading any of
the values you write to them. the following bits will return %0, regardless of the values you
Bit 0: This bit controls whether or not the output for voice 1 write to the bits.
passes through the SID's filter stage. When the bit is %0, the
filter is bypassed and voice 1 output is routed directly to the Bits 0-3: These bits specify the peak volume for the combined
combined SID output. When the bit is % 1 , voice 1 output is output of all three voices plus any external input. The four bits
routed through the filter before being passed to the chip out- allow for 16 evenly spaced steps between no output (%0000)
put. The filter will modify the voice 1 output according to the and maximum output (%1111). Expressed as a percentage of
filter parameters specified in the registers at 54293-54294/ maximum possible output volume, the effects of the settings
$D415-$D416 and 54296/$D418. are roughly as follows:
Bit 1: This bit provides the same filter control function for
voice 2 that bit 0 provides for voice 1.
399
54296 $D418 $D418 54296
type of filter known as the band-stop, or notch, filter (see Fig- called analog-to-digital (A/D) converters. The A/D converters
ure 8-14d). In this case, frequencies well above and below the generate a one-byte value based on the input voltage. These
cutoff are passed with little change, while frequencies near the read-only registers return the values generated by the convert-
cutoff are attenuated. The cutoff frequency is specified in the ers; writing to these locations has no effect. As connected in
registers at 54293-54294/$D415-$D416. the 128, the converters measure the voltage across capacitors
Bit 4 controls the low-pass filter, which is enabled when at the input pins. When a variable resistor (also called a poten-
the bit is %1 and disabled when the bit is %0. Bits 5 and 6 tiometer) is connected between a constant voltage source and
provide the control for the high-pass and band-pass filters, re- the capacitor, the converters can be used to read the input re-
spectively, in the same manner. Thus, standard filter selections sistance. The output values will be in the range 0-255, accord-
are as follows: ing to the resistor value. Minimum resistance (or a closed
circuit) produces a reading of 0/$00 and maximum resistance
Bits Value Filter type (or an open circuit, as when nothing is connected to the lines)
6 54 results in a reading of 255/SFF. The official SID chip specifica-
001 16/$10 Low-pass tions state that the relationship between the installed capacitor
0 10 32/$20 Band-pass values and the resistance for maximum output value is:
10 0 64/S40 High-pass
10 1 80/$50 Band-stop resistor value = 4.7 X 10~ 4 / capacitor value
Bit 7: This bit controls whether or not voice 3 can be con- The capacitors in the 128 are 1800 picofarads (1800 X 10"12),
nected directly to the combined output of the SID chip. While so any resistance greater than about 4.7 X lO"4 / 1800 X
the bit is %0, the voice 3 output will be added to the com- IO-12 = 261 X 103 ohms (261 Kfl) will result in a register
bined output unless it is routed through the filter. Setting this value of 255/$FF. (Actually, our experience indicates that a
bit to %1 will prevent the direct connection of voice 3 to the slightly higher value, 270-280 KQ or so, may be required.)
combined output. However, even when voice 3 is blocked The SID input lines can be connected to either of the two
from direct connection to the combined output, it's still possi- control ports on the right side of the 128. Bits 6-7 of the CIA
ble to route voice 3 output through the filter and hence to the #1 port A register at 56320/$DC00 determine which control
combined output. To prevent this and completely disconnect port is currently connected (for details, see the section on the
voice 3, make sure that bit 2 of the register at 54295/$D417 is CIA chip later in this chapter). The default setting connects
set to %0. control port 1, the front one. For either port, the SID register
Voice 3 is often used in conjunction with one of the other lines are connected to port pins 5 and 9. Location 54297/
voices to generate special audio effects, since the oscillator and $D419 will read the level at pin 9 and location 54298/$D41A
envelope generator output values for this voice can be read will read the level at pin 5. From BASIC, the POT function
from registers 54299/$D41B and 54300/$D41C, respectively. can be used to read these registers. POT(l) reads the register
While voice 3 is used to generate special envelopes or as a at 54297/$D419 connected to pin 9 of port 1 and POT(2)
random-number generator, it's desirable to insure that the reads the register at 54298/$D$lA connected to pin 5 of port
specified frequency and envelope for voice 3 don't cause any 1. POT(3) and POT(4) read the same registers when con-
disruption of the other voices. This bit provides that feature. nected, respectively, to pins 9 and 5 of port 2.
Voice 3 is the only voice which can be disconnected. The device most commonly connected to these inputs is
the game paddle controller. A paddle is an extremely simple
54297 SD419 POTX device, consisting of a variable resistor connected between a
54298 8D41A POTY + 5 volt source (pin 7 of the control port) and the SID A/D
converter input line. Turning the paddle knob changes the re-
Potentiometer (paddle) reading registers sistance, and hence the register value. The paddle tends to be
The SID chip has two special input lines, designated POTX more efficient than the joystick for games that require only
and POTY, which are connected to a pair of internal devices
402 403
54298 $D41A $D41B 54299
horizontal or only vertical movement, such as Pong-type consists of two variable resistors—one on the horizontal axis
games for which the paddle was originally developed. Since and one on the vertical axis.
the steps between output levels are so small (only about one
ohm), consecutive readings of the same paddle position can 54299 $D41B OSC3
vary by one or two register values. This "jitter" can be annoy- Voice 3 oscillator output register
ing. The recommended solution is to read the paddle several This register reflects the upper eight bits of the internal-oscillator
times, then calculate the average of the readings and use that register for voice 3. This is a read-only register; storing values
value. here has no effect. The output signal for each voice is gener-
One thing you should be aware of is that Commodore has ated by converting the digital bit pattern from the voice's os-
changed the values of the capacitors used with the converters cillator register into an analog voltage level, so the output
since the Commodore 64 was first introduced. The original 64 signal for the voice is directly proportional to the value in its
used 1000 picofarad capacitors, so a resistance of about 470 oscillator. However, voice 3 is the only voice for which the os-
KX2 was required for a maximum register value. Thus, most cillator contents can be read.
paddles currently available for Commodore computers use For triangle and sawtooth waveforms, the oscillator acts
potentiometers with a top resistance of 470 Kf2 or 500 KQ. as a repeating counter. For the triangle waveform, the oscil-
Such paddles can be used with the 128, but they will swing lator count starts at zero and increments upward to its maxi-
the full range of register values (0-255) in about the first half mum count, then decrements downward to zero again. Once
of the paddle's full turn. Thus, you probably won't be able to the count reaches zero, it immediately begins incrementing
select fine increments of intermediate values. Furthermore, again, and the process repeats over and over. The counting
paddles for Atari computers, which are much more widely rate depends on the value in the frequency control registers
available than Commodore paddles, use 1 M£l (1 million ohm) for the voice. For all but the lowest frequencies, the count
potentiometers. Again, these can be used with the 128, but in sweeps up and down so quickly that you won't read every in-
this case you'll see the full register value swing (0-255) in termediate value between 0/$00 and 255/$FF in this register.
about the first quarter of the paddle's ful] turn. Thus, Atari For the sawtooth waveform, the count also starts at zero and
paddles will give you only very coarse control of the resulting increments upward to maximum count, but in this case the
register values. count then returns immediately to zero and begins increment-
Most paddle controllers also have fire buttons like joy- ing again.
sticks. However, since paddles almost always come in pairs, Unlike the triangle and sawtooth waveforms, the pulse
and since there is only one fire button line per control port, waveform doesn't sweep smoothly from one output level to
the paddle fire buttons are connected to the lines normally the next. Instead, the it jumps back and forth between two
used for joystick direction. Standard Commodore paddles use discrete levels. When the pulse waveform is selected for voice
the lines connected to bits 2 and 3 of each CIA #1 data port 3, this register will contain one of two values: 0/$00 when the
(locations 56320-56321/$DCOO-$DC01), the lines for joystick waveform is at minimum (zero) amplitude and 255/$FF when
left and right. the waveform is at maximum amplitude. The portion of the
These A/D converters can also be used for other interfac- cycle spent in the zero-amplitude state is determined by the
ing projects. Any device which provides a variable resistance value in the pulsewidth registers for the voice, and the rate at
can be connected to the appropriate control port lines and which the off/on switching repeats is determined by the value
read via these registers. For example, most graphics tablets in the frequency control registers for the voice.
such as the popular KoalaPad effectively function as paddles, The noise waveform is different from the others in that it
with one resistance for the horizontal coordinate of the stylus exhibits no regularly repeating pattern. Rather, the oscillator
position and another for the vertical coordinate. You could will contain a series of random values. The rate at which the
also rig an interface for an Apple/IBM-style joystick, which value in the oscillator changes—and hence the rate at which
404 405
54300 $D41C $D41C 54300
54301-54303 $D41D-$D41F Unused The 17 registers of the MMU are unusual in that they are
These unused register locations always return the value 0/$00 divided into two separate groups at different memory loca-
when read. Writing to these locations has no effect. tions. The first 12 appear in the I/O block at 54528-54539/
$D500-$D50B, while the other 5 appear at 65280-65284/
54304-54527 $D420-$D4FF $FF00-$FF04. This second set of MMU registers is special in
SID register images that it appears in all memory configurations. There is no way
Due to incomplete address decoding, images of the SID chip to make the processor see anything other than the MMU regis-
registers appear repeatedly every 32 locations throughout the ters at those locations while the 128 is in 128 mode. Table 8-4
remainder of this page of memory. That is, storing a value in lists the MMU registers. A detailed description of each register
any location with an address which is an exact multiple of 32 follows.
greater than one of the base address locations listed above has Table 8-4. MMU Chip Registers
the same effect as storing a value in the corresponding base
register. For example, storing a value in 54328/$D318 or Address Function
54520/$DF18 has the same effect as storing that same value 54528/$D500 Configuration register
in 54296/$D018. However, it's better programming practice to 54529/$D501 Preconfiguration register A
use the officially designated register addresses. 54530/$D502 Preconfiguration register B
54531/$D503 Preconfiguration register C
54532/$D504 Preconfiguration register D
MMU (Memory Management Unit) Chip 54533/SD505 Mode configuration register
54534/$D506 RAM configuration register
Registers 54535/$D507 Page 0 page pointer
54528~54539/$D500-$D50B and 54536/$D508 Page 0 block pointer
65280-65284/$FF00-$FF04 54537/$D509 Page 1 page pointer
54538/$D50A Page 1 block pointer
The MMU memory management chip, officially designated the MMU version register
54539/$D50B
8722, is the cornerstone of the 128 system. In fact, the MMU 65280/$FF00 Configuration register
is what makes most of the 128's special features possible. The 65281/$FF01 Load configuration register A
MMU was designed by Commodore's engineers specifically to 65282/$FF02 Load configuration register B
support the 128's multiple operating modes and elaborate 65283/$FF03 Load configuration register C
memory banking scheme. It is the MMU which determines 65284/$FF04 Load configuration register D
which microprocessor, 8502 or Z80, has control of the com-
puter. When the 8502 is in control, the MMU determines 54528 SD500 MMUCR1
whether the computer operates in 128 mode or 64 mode. As Configuration register
described in Chapter 1, the 128 hardware includes many times The value in the configuration register determines which of
more elements than can simultaneously fit in the 64K address the available memory resources will be visible to the
space of the 8502 or Z80 microprocessors. The MMU chip also microprocessor at any given time. However, this particular
determines which memory resources are visible to the register is only rarely used—-not at all in 128 ROM except dur-
processsor at any given time. ing MMU register initialization—because it has an identical
Most BASIC programming can be done without under- twin at address 65280/SFF00 which is more convenient. There
standing the inner workings of the MMU, simply by using the is really only one configuration register; it just appears at two
available standard bank configurations. However, a thorough different addresses. The register is accessible here only when
knowledge of the MMU is essential for taking full advantage the I/O block is visible, whereas it is always accessible at
of all the 128's features. 65280/$FF00, regardless of the memory configuration. As a
408 409
54529 $D501 SD505 54533
instruction there when you activate the Z80—for example, if Bits 4-5: These bits are connected, respectively, to the MMU
the system is in a memory configuration such as bank 15 pins labeled GAME and EXROM, which in the 128 are con-
where 128 Kernal ROM is seen at that address—you'll proba- nected to the memory expansion port lines with the same
bly experience an immediate system lockup. names. These MMU lines are bidirectional, meaning that they
If you wish to use any routines in the CP/M BIOS (Basic can be both inputs and outputs. The 128 uses the lines only as
Input/Output System) ROM, you must make sure that bit 6 of inputs, to read the state of the memory expansion port lines
this register also is set to make 128 mode ROM visible. The (pins 8 and 9 of the port). Writing to one of the bits sets the
BIOS code is stored in the same ROM chip used to hold the corresponding line's output level. Writing a %0 to the bit pulls
128 mode screen editor and Kernal routines, so you'll have the line to a low (0 volts) state, while writing a %1 to the bit
problems if that ROM is not visible. Activating the Z80 makes allows the line to go to a high ( + 5 volts) state. When used for
the BIOS ROM visible at addresses 0-4095/$0000-$0FFF input, an external device connected to the line can pull the
(even though the ROM is physically located at 53248-57343/ line low if its output level is set high, but cannot bring the line
$DO00-$DFFF). Thus, the Z80 never disturbs the lowest 4K of high if its output level is set low, so writing a %0 to one of
block 0 RAM, so the 8502's zero page and stack (page 1) are these bits effectively blocks the use of the line as an input.
preserved while the Z80 is in control.
The Kernal RESET routine [$E000] initializes both of these
If you want to switch to full CP/M mode, there's more in- bits to %1 so that they can be used to read the state of the
volved than simply turning on the Z80. Most of the CP/M op- port lines. In 128 ROM, these bits are read during the reset se-
erating system must be loaded from disk, so you should instead quence by the routine which checks for the presence of a
use the BASIC BOOT statement or the Kernal BOOT_CALL Commodore 64 ROM cartridge [$E242], Almost all Commo-
routine [$FF53] with a CP/M boot disk in the drive. dore 64 cartridges ground one or both of these port lines, so
Bits 1-2: Unused. These bits always return %1 when read, the 128 will assume that a 64 cartridge is present if either of
and writing to these bits has no effect. these bits is found to be %0, and will respond by switching to
Bit 3: This bit is connected to the MMU pin labeled FSDIR. Commodore 64 mode.
This line is bidirectional, meaning that it can be both an input While the system is in 128 mode, you can use these bits
and an output. The 128 uses the line only as an output, to to control the corresponding expansion port pins as either in-
control the direction of data flow on the fast serial bus. The puts or outputs. Keep in mind, however, that the pins must be
lines of the slow serial bus are each controlled by a pair of high during reset or the system will enter Commodore 64 mode.
CIA chip lines, one for input and one for output, but the fast Bit 6: This bit controls which set of ROMs will be visible to
serial bus uses the same CIA chip lines for both input and out- the system. Writing a %0 here selects the 128 mode ROM set,
put. The 128's designers added additional circuitry which in- while writing a %1 selects the Commodore 64 mode ROM.
sures that the fast serial bus will ignore incoming data during The 128 mode RESET routine [$EOOOj, of course, initializes
fast serial output. The FSDIR (fast serial direction) line controls this bit to %0. However, simply writing a %1 here won't
that circuitry. Writing a %0 to the bit pulls the line to a low (0 cause a clean transfer to 64 mode; it's necessary to perform
volts) state, which sets the fast serial bus for input. Writing a the 64 mode reset sequence after the 64 mode ROM is se-
%1 to the bit allows the line to go to a high ( + 5 volts) state, lected. See the C64_MODE routine [$E24B] for details. This
which sets the fast serial bus for output. The IOINIT routine bit has one other effect—selecting 64 mode also makes all the
[$E109] leaves this bit set to %0 so that the system can detect MMU chip registers invisible, so once you make the jump to
fast serial input. The setting of this bit is controlled in Kernal 64 mode there is no way back to 128 mode short of resetting
ROM by the routines SPIN [$E5C3] and SPOUT [$E5D6]. the computer or turning it off and back on.
412 413
54534 3D506 SD506 54534
Bit 7: This bit is connected to the MMU pin labeled 40/80. There are a few exceptions to the common RAM rules.
This line is bidirectional meaning that it can be both an input First, locations 0-l/$00-$01, the 8502 on-chip I/O port, and
and an output. The 128 uses the line only as an input, to read locations 65280-65284/$FF00-$FFO4, the upper MMU regis-
the 40/80 DISPLAY switch on the 128's keyboard. Writing to ters, always appear in any configuration, regardless of the
the bit sets the state of the line output. Writing a %0 to the bit setting of these bits. That is, there is no way to make the pro-
pulls the line to a low (0 volts) state, while writing a %1 to cessor see anything other than the hardware registers in these
the bit allows the line to go to a high ( + 5 volts) state. The locations (at least not while the computer is operating in 128
switch connected to the line can pull the line low if its output mode). Second, the area where the two lowest pages of mem-
level is set high, but cannot bring the line high if its output ory are seen is also affected by the registers at 54535-54538/
level is set low. Thus, writing a %0 to this bit effectively $DF07-$DF0A. Even if you change the page pointers at
blocks the reading of the 40/80 DISPLAY switch. The CINT 54535/$D507 or 54537/SD509 to physically move zero page
screen editor initialization routine [SC07B], part of both the re- or page 1 somewhere in memory outside the common area,
set and RUN/STOP-RESTORE sequences, sets this bit to %1 the contents of those pages will still appear to be common as
to insure that the switch can be read. The bit returns a %0 long as a common area at the bottom of memory is selected. If
when read while the switch is down (80-column position), or you disable the common area at the bottom of memory, all
a %1 while the switch is up (40-column position). In 128 references to zero page and page 1 will continue to affect only
ROM, this bit is read only during the CINT routine, where its block 0 RAM unless you specifically change the block pointers
setting is used to determine which display to make active. for those pages in the registers at 54536/SDF08 and 54538/
$DF0A. Finally, you should be aware that the common area
54534 8D506 MMURCR setting does not affect the RAM block from which the VIC
RAM configuration register chip sees its video bank. The VIC's RAM block is determined
An important aspect of the MMU's memory configuration ca- by bits 6-7 of this register, and all RAM in the VIC bank is
pabilities is its ability to create common areas of RAM, areas seen in the block specified in those bits without regard for the
where the same RAM is seen regardless of the configuration common area specification. The VIC chip can see the memory
register selection. Kernal routines copied into the default com- that is hidden from the processor.
mon area allow the processor to jump from bank to bank, or The four possible selections for the size of the common
to manipulate data in other banks. This register controls the areas are as follows:
common RAM feature, and also specifies which RAM block Hits Size of
the VIC video banks are seen in. 1 0 common areas
Bits 0-3: These bits control the common RAM feature. Bits 0-1 0 0 IK
control the size of the common areas, and bits 2-3 control 0 1 4K
1 0 8K
whether the common areas will exist at the top, bottom, or 1 1 16K
both top and bottom of the RAM blocks. (No RAM will be
common if bits 2-3 are set to %00.) When common RAM is Figure 8-15 illustrates the address ranges of these selections.
specified, the RAM seen as common is always that from block The four possible selections for location of the common
0. As long as the common RAM feature is enabled, there is no areas are as follows:
way for the processor to access the RAM in block 1 which is
covered by the common area. When a common area at the top Location of
common areas
of memory is selected, it will be visible only when bits 4-5 of No common RAM
the configuration register are set to make RAM visible at the Common area at bottom of memory
top of memory. Common area at top of memory
Common areas at both top and bottom of memory
414 415
54534 $D506 $D506 54534
Figure 8-15. Common RAM Areas The default value in these bits, established during the Kernal
RESET routine [SEOOO], is %0100 = $4. This setting selects a
IK common area at the bottom of memory, addresses 0-1023/
$0000-$03FF. The proper functioning of both the operating
system and BASIC depends on the presence of this common
area, so you should change the setting of these bits with great
care. BASIC is almost certain to crash if the common area is
disabled altogether. The operating system will crash if an in-
terrupt occurs while the system is configured for block 1 RAM
with the common area disabled.
You can manipulate these bits to gain temporary access to
the IK of RAM from block 1 which is normally hidden by the
standard common area, but making any practical use of the
hidden area is more than a little complicated. The standard in-
terbank data transfer routines like INDFET and INDSTA can't
be used because they depend on the common area. Further-
more, the machine language routine you write to perform the
transfer can't use any zero-page locations, nor can it use jumps
to subroutines or other instructions which would affect the
stack (page 1). Interrupts must also be disabled while the com-
mon area is disabled. The following routine swaps the con-
tents of the hidden block 1 area with the contents of the next
higher IK area of block 1 (addresses 1024-2047/$0400-$07FF).
Note that this routine must be placed in block 1 RAM:
1FF60 SEI ;Disable interrupts
1FF61 LDA #$7E ;Make I/O block visible
1FF63 STA $FF0O
1FF66 LDA #$00 ;Disable common RAM
1FF68 STA $D506
1FF6B LDA #$01 ;Make pages 0 and 1 visible
1FF6D STA $D508 ; block 1 RAM
1FF70 STA $D50A
1FF73 LDA #$00
1FF75 STA $D507
1FF78 LDA #$01
1FF7A STA $D509
1FF7D LDA #$00 •Initialize source starting
1FF7F STA $FF91 ; address locations
1FF82 STA $FF98
1FF85 LDA #$04 initialize target starting
1FF87 STA $FF95 ; address locations
1FF8A STA $FF9C
1FF8D LDY #$02 initialize index for first page
1FF8F LDA $0000,Y ;Swap bytes
416
417
54534 $D506 $D5O8 54536
1FF92 TAX
1FF93 LDA $04O0,Y Bits RAM block for
1FF96 STA $000O,Y 7 6 VIC video bank
1FF99 TXA 0 0 0
1FF9A STA $O4O0,Y 0 1 1
1FF9D INY 1 0 2
;Repeat for 256 bytes per page
1FF9E BNE $FF8F 1 1 3
1FFA0 INC $FF91 i n c r e m e n t address high bytes Remember, however, the 128 actually has only two 64K
1FFA3 INC $FF95 blocks of RAM. Thus, the setting of bit 7 is meaningless, al-
1FFA6 INC SFF98 though that bit will retain whatever value you write to it.
1FFA9 INC $FF9C Only the setting of bit 6 matters, since the choice is between
1FFAC LDA $FF9C ;Check whether all four pages have blocks 0 and 1. The default setting for these bits is %00, since
1FFAF CMP #$08 ; been swapped the normal VIC text and bitmapped screens are located in
1FFB1 BCC $FF8F block 0 RAM.
1FFB3 LDA #$00 ;I( so, restore pages 0 and 1
1FFB5 STA $D508 You should note that the operating system and BASIC
; to block 0 RAM
1FFB8 STA $D50A will not support a VIC video bank in block 1, That is, all the
1FFBB STA $D507 screen editor ROM routines and BASIC bitmapped graphics
1FFBE LDA #$01 routines assume that the VIC screen is located in block 0
1FFCO STA $D509 RAM, and will continue to write data to block 0 even after
1FFC3 LDA #$04 ;Reenable common RAM you've changed these bits to switch the video bank into block
1FFC5 STA $D5O6 1 RAM. Thus, you must provide your own text and graphics
IFFC8 CLI ;Reenable interrupts routines for a display from block 1. For text displays, you can
1FFC9 RTS use the standard character sets because the character ROM is
To execute the routine, use J 1FF60 from the monitor or BANK still visible in a block 1 video bank.
1:SYS 65376 from BASIC. These bits actually determine the RAM block for all DMA
(direct memory access) operations, not just for the VIC chip,
but the VIC is the only built-in device in the 128 to use DMA.
Bits 4-5: These two bits are not used in the current version of
The only other commonly available DMA device for the 128 is
MMU. The design specifications for the chip indicate that in
the REC (RAM expansion controller) chip in the 1700 and
future versions these bits may be used in a "superbanking" 1750 Memory Expansion Modules. These bits, rather than bits
scheme to select one of four separate 256K blocks of RAM in a 6-7 of the configuration register, determine which block of
1M (one-megabyte, or 1024K) system. It's a tantalizing pros- 128 system RAM is affected by REC transfer operations.
pect, but there's no guarantee that a Commodore 1024 will
ever be produced. In the current MMU, the bits will retain 54535 8D507 MMUPOL
whatever value is written to them, but changing the bit 54536 $D508 MMUPOH
settings has no effect on the memory configuration. The bits Page 0 pointers
are initialized during the Kemal RESET routine [$E000] to %00.
Bits 6-7: These bits determine which 64K block of RAM the One unique feature provided by the MMU is the ability to re-
locate page 0 anywhere in memory. Zero page is the most
VIC video bank is located in. (See the section on the VIC chip
heavily used area of memory in any computer built around a
earlier in this chapter for more information on video banks.)
6502-family microprocessor like the 128's 8502, since the pro-
The formally defined selections for the bits are as follows:
cessor has many instructions that are designed to work only
with this page. Although neither the 128 operating system or
BASIC makes use of this page-relocation capability, it has sev-
418 419
54536 SD508 SD50A 54538
eral interesting applications. For example, you could have sev- rarely a need to change the value in 54536/$D508. If you se-
eral programs in memory simultaneously and give each its lect block 1 RAM while the bottom common area is enabled, a
own personal zero page, without having to worry about mem- strange effect results. Zero page is relocated to the page speci-
ory conflicts. fied in the page pointer, but that page is not swapped with
Location 54535/$DF07, the page pointer, selects the page zero page. That is, both pages will occupy the same area of
of memory to which zero page is to be relocated. The Kernal memory, and the true zero-page area remains untouched.
RESET routine [$E0O0] stores the value 0/$00 here to locate When choosing areas of memory for a relocated zero
zero page initially in the true zero page. To move zero page, page, you must avoid page 1 (or the area where you relocate
store the target page number here. {The page number is equiv- page 1), since that page is also vital to proper system opera-
alent to the high byte of the first address in the page.) Actu- tion. You should also avoid page 255/$FF, since attempting to
ally, the operation is more a swap than a relocation. When place zero page there will cause conflicts with the MMU regis-
you redirect zero page to another page of memory, all refer- ters. Because all references to the target page will affect true
ences to addresses in the target page are diverted to the true zero page, you should be careful to avoid using any locations
zero page. For example, if you store the value 19/$13 in this in the target page while zero page is relocated (unless you
register to move zero page to page 19, then all references to really want to change true zero page). After relocating zero
addresses in the range 2-255/$02-$FF will be redirected to page, you will probably want to call the Kernal routines
4866-5119/$1302-$13FF, and all references to 4864-5119/ RAMTAS [$FF87] and CINT [$FF81] to initialize important
$1300-$13FF will be redirected to 0-255/$00-$FF. Notice that zero-page locations. (If you switch to a zero page without
addresses 0-1 from zero page are not affected. These are the proper screen editor variables, you may find yourself looking
processor's on-chip I/O port registers—not RAM. Storing values at a garbled mess on the screen.)
in these locations always affects the registers rather than RAM.
Location 54536/$D508 selects the block of RAM in which 54537 $D509 MMUP1L
zero page will be seen. Only bit 0 of the block pointer is sig- 54538 SD50A MMUP1H
nificant. Setting that bit to %0 selects block 0 RAM, while set- Page 1 pointers
ting it to %1 selects block 1. The bit is set to %0 by the Kernal
RESET routine [$E000]. Bits 1-3 will retain whatever value is Just as the MMU can relocate zero page, it also has the ability
written to them, but changing these bits has no effect. The RE- to make page 1 appear anywhere in memory. Page 1 is vital in
SET routine sets these bits to %000, Bits 4-7 are also unused, any computer built around a 6502-family microprocessor like
but these bits always return %1 when read. As a result, the the 128's 8502, since that page is the processor stack. The
value in this register will always be at least 240/$F0. Values stack is the area of memory where the processor stores return
written to the page pointer take effect immediately, but values addresses while it is executing subroutines or handling inter-
written to the block pointer are actually effective only after the rupts. The stack is also used extensively for temporary data
next time a value is stored in the page pointer. Thus, if you storage. Although neither the 128 operating system or BASIC
are changing both registers it is important to remember to makes use of this page-relocation capability, it has several in-
store the value in the block pointer (54536/$DF08) before teresting applications. For example, you could have several
storing the value in the page pointer (54535/$DF07). programs in memory simultaneously and give each its own
However, the block pointer value is ineffective while the personal stack, without having to worry about memory conflicts.
RAM configuration register (54534/$D506) is set to provide a Location 54537/$DF09, the page pointer, selects the page
common area at the bottom of memory. With the bottom com- of memory to which page 1 is to be relocated. The Kernal RE-
mon area enabled, zero page is always seen in block 0 RAM, SET routine [$E000] stores the value 0/$01 here to locate page
although it can still be moved around freely within block 0. 1 initially in the true page 1. To move page 1, store the target
Since this is the default configuration for the 128, there is page number here. (The page number is equivalent to the high
byte of the first address in the page.) Actually, the operation is
420 421
54538 $D50A 6D50B 54539
more a swap than a relocation. When you redirect page 1 to serve the original stack pointer; otherwise, your program will
another page of memory, all references to addresses in the tar- crash when the memory moving subroutine tries to return to
get page are diverted to the true page 1. For example, if you its calling routine. The two routines below are alternate meth-
store the value 21/$ 15 in this register to move page 1 to page ods of filling the high-resolution screen area. The conventional
21, then all references to addresses in the range 256-511/ method (on the left) is shorter, but the relocated stack method
$0100-$01FF will be redirected to 5376-5631/$1500-$15FF, (on the right) is about 30 percent faster.
and all references to 5376-5631/$1500-$15FF will be re-
BOO LDA #$00 COO TSX
directed to 256-511/$0100-$01FF. STA $FB C01 STX $FB
B02
Location 54539/$D50A selects the block of RAM in B04 LDA #$20 C03 LDX #$FF
which page 1 will be seen. Only bit 0 of the block pointer is B06 STA $FC COS TXS
significant. Setting that bit to %0 selects block 0 RAM, while BOS LDA #$FF C06 LDA #20
setting it to %1 selects block 1. The Kernal RESET routine BOA LDX #$20 COS STA $D509
[$E000] sets this bit to %0 for block 0. Bits 1-3 will retain B0C LDY #$00 COB LDA #$FF
whatever value is written to them, but changing these bits has B0E STA ($FB),Y COD LDX #$20
no effect. The bits are set by the RESET routine to %000. Bits B10 INY C0F LDY #$00
4-7 are also unused, but these bits always return %1 when Bll BNE $B0E Cll PHA
read. As a result, the value in this register will always be at B13 INC $FC C12 INY
B15 DEX C13 BNE $C11
least 240/$F0. Values written to the page pointer take effect C15 INC $D509
B16 BNE $C11
immediately, but values written to the block pointer are actu- CIS DEX
B18 RTS
ally effective only after the next time a value is stored in the C19 BNE $C11
page pointer. Thus, if you are changing both registers it is im- C1B LDX SFB
portant to remember to store the value in the block pointer C1D TXS
(54538/$DF0A) before storing the value in the page pointer C1E LDA #$01
(54537/$DF09). C20 STA $D509
However, the block pointer value is ineffective while the C23 RTS
RAM configuration register (54534/$D506) is set to provide a
common area at the bottom of memory. With the bottom com- 54539 $D50B MMUVER
mon area enabled, page 1 is always seen in block 0 RAM—al- Version register
though it can still be moved around freely within block 0, This read-only register returns a constant value (much like a
Since this is the default configuration for the 128, there is ROM location) reflecting the amount of RAM in the system
rarely a need to change the value in 54538/$D50A. If you se- and the version of the MMU. If Commodore ever introduces
lect block 1 RAM while the bottom common area is enabled, a successors to the 128 built with similar system architecture (a
strange effect results. Page 1 is relocated to the page specified Commodore 256 or 1024, for example), this register will allow
in the page pointer, but that page is not swapped with page 1. software to identify the amount of memory available.
That is, both pages will occupy the same area of memory, and Bits 0-3: These four bits indicate the version of the MMU chip
the true page 1 area remains untouched. installed in the 128. In current 128s the value here is %0000
This mobile page 1 allows a tricky technique for filling = 0, indicating version 0 of the MMU, but this may change if
areas of memory. Instead of storing values in a series of loca- new versions of the chip are introduced.
tions, you can redirect page 1 to the desired area of memory Bits 4-7: These four bits indicate the number of 64K blocks of
and push values onto the relocated stack. The advantage of RAM present in the system. In the 128, the value here is
this is that the PHA instruction takes only half as long to exe- %0010 = 2, indicating 128K of RAM in two 64K blocks.
cute as the STA (address),Y instruction. Just be sure to pre-
422 423
54540-54783 $D50C-$D5FF 6FF00 65280
54540-54783 $D50C-$D5FF Unused cess to the configuration register to make the I/O block visi-
All the unused register addresses in this range return the value ble). Both registers will hold identical values, regardless of
255/SFF when read. Writing to these locations has no effect. which register is written to set the value.
There is an alternative to storing values directly in this
65280 $FF00 MMUCR register. You can store up to four configuration register
Configuration register settings in the preconfiguration registers at 54529-54532/
This is one of the most important locations in all of 128 mem- $D501-$D504, then transfer the values to the configuration
ory, since the value here determines what other memory ele- register by writing to the corresponding load configuration
ments will be visible to the processor. The entire design of the registers at 65281-65284/$FF01-$FF04. See the precon-
128 is contingent on the MMU's ability to make various selec- figuration and load configuration register entries for details.
tions of the system's memory resources visible at shared loca- Bit 0: This bit determines what is seen at addresses in the
tions within the processor's limited address space. The 16 range 53248-57343/$D000-$DFFF. When the bit is set to %0,
banks supported by the operating system are merely 16 pre- the I/O block (containing hardware chip registers and color
defined settings of this register—not 16 physical arrangements RAM) is visible. When the bit is set to % 1 , the contents of the
of memory. See Table 1-1 in Chapter 1 for details of the stan- address area is determined by the setting of bits 4-5.
dard bank configurations. Bit 1: This bit determines what is seen at addresses in the
Configurations other than the standard banks are certainly range 16384-32767/$4000-$7FFF. When the bit is set to %0,
possible. Since each of the eight bits of this register is assigned the lower portion of BASIC ROM appears there. When the bit
a function in the MMU specifications, there are theoretically is set to % 1 , the address area will contain RAM from the block
256 possible different memory configurations. Actually, there specified in bits 6-7.
are only 128 functional combinations because bit 7 of the reg-
ister in not implemented in the current version of the MMU. Bits 2-3: These bits determine what is seen at addresses in the
However, not all of these possible configurations are equally range 32768-49151/$8000-$BFFF. The four possible selections
useful. For example, none of the configurations which involve are as follows:
either internal or external function ROM are useful unless you Bits
have a function ROM installed. The only configuration regu- 3 2 Address range contents
larly employed by the system that doesn't correspond to a 0 0 Upper portion of BASIC ROM ($8000-$AFFF), plus monitor
standard bank is one used by BASIC, consisting of BASIC ROM ($BOOO-$BFFF)
ROM, screen editor ROM, character ROM, and Kernal ROM, 0 1 Internal function ROM
plus block 1 RAM (essentially the same as bank 14, but with 1 0 External function ROM
1 1 RAM
RAM from block 1 instead of block 0). Machine language pro-
grammers may find it useful to set up a configuration which Internal function ROM refers to ROM in the free ROM socket
switches out BASIC ROM while retaining the I/O block and on the 128 circuit board. External function ROM refers to
screen editor and Kernal ROM, Such a configuration leaves 4IK ROM in a cartridge plugged into the expansion port. If you se-
free for ML programs in the range 7168-49151/$1COO-$BFFF. lect either of these sources when no ROM is actually installed,
To set up this arrangement, use LDA #$0F:STA $FFOO. the area will appear to contain unpredictable changing values.
When RAM is selected in this area, the block from which the
This location has an identical twin at address 54528/
RAM will be seen is determined by the setting of bits 6-7.
$D500. Actually, there is only one configuration register, but it
can be accessed at two different addresses. The higher address Bits 4-5: These bits determine what is seen at addresses in the
is used almost exclusively because it is visible in all memory range 49l52-65535/$C000-$FFFF, with some exceptions. The
configurations, whereas the register is visible at 54528/$D500 MMU configuration and load configuration registers always
only when the I/O block is selected (and you must have ac- appear at 65280-65284/$FF00-$FF04, regardless of the
424 425
65280 $FF00 $FF04 65284
settings of these bits. Also, bit 0 of this register can override MMU. Bit 7 will retain whatever value you write to it, but
the specification for the contents of addresses in the range only bit 6 is significant.
53248-57343/$D000-$DFFF. As long as bit 0 is set to %0, the The block specification in these bits will be overridden for
I/O block will be seen in that portion of this area, regardless certain ranges of memory if any common RAM areas are spec-
of the setting of these bits. The four possible selections for this
area are as follows: ified by the RAM configuration register at 54534/$D506.
When common areas are enabled, any visible RAM in the
Bits common range will be seen from block 0, regardless of the set-
5 4 Address area contents ting of these bits.
0 0 Screen editor ROM ($COOO-$CFFF), character ROM
These bits specify the RAM block for the processor only;
($D00O-$DFFF), Kemal ROM ($EOOO-$FFFF) the block in which the VIC (40-column) chip's video RAM
Internal function ROM
External function ROM bank is seen can be selected independently. The VIC block is
RAM specified in bits 6-7 of the MMU's RAM configuration register
at 54534/$D506. The RAM configuration register bits, rather
Internal function ROM refers to ROM in the free ROM socket than the configuration register bits, also determine which
on the 128 circuit board. External function ROM refers to block will be affected by other DMA (direct memory access)
ROM in a cartridge plugged into the expansion port. If internal operations, such as data transfers by the REC (RAM expansion
or external function ROM is selected when no ROM is actually controller) chip in the RAM expansion modules.
present, the area will appear to contain unpredictable chang-
ing values. When RAM is selected, the area will contain RAM 65281 SFF01 LCRA
from the block specified in bits 6-7, unless the MMU's RAM 65282 $FF02 LCRB
configuration register at 54534/$D506 specifies a common 65283 $FF03 LCRC
area at the top of memory. When a common area is enabled, 65284 $FF04 LCRD
all RAM in the common area will come from block 0, regard- Load configuration registers
less of the block specified in bits 6-7.
Each of these registers has a corresponding preconfiguration
Bits 6-7: The memory configuration established by the 128 al- register at 54529-54532/$D501-$D504. Storing a value in a
ways includes RAM in the lowest 16K area (addresses load configuration register causes the value in the precon-
2-16383/$0002-$3FFF), and RAM may be selected in any of figuration register to be transferred to the configuration regis-
the other three 16K segments in the processor's 64K address ter. The value stored in the load configuration register is
space. These bits determine which 64K RAM block the RAM irrelevant; it is the store operation, rather than the value
in the selected configuration will be seen from. The formal stored, which causes the transfer. Reading any of the load
specifications for these bits are as follows: configuration register locations returns the value in the cor-
Bits responding preconfiguration register. Values stored in a load
7 6 RAM block selected configuration register location have no effect on the value re-
0 0 Block 0 turned when the register is read.
0 1 Block 1 The 128 operating system does not use the preconfigur-
1 0 Block 2 ation or load configuration registers, but BASIC does. See the
1 1 Block 3 entry above for the preconfiguration registers for details of the
Remember, however, that the 128 actually has only two 64K standard configuration settings.
blocks of RAM (blocks 0 and 1). Thus, the setting of bit 7 is
meaningless and has no effect in the current version of the
426 427
54784-54785 $D600-$D601 6D600-$D601 54784-54785
VDC (Video Display Controller) Chip Although the VDC does have a graphic mode (see the en-
Registers try for bit 7 of register 25/$19), it is primarily used for text
54784-54785/$D600-$D601 displays. In this mode, it uses the same basic elements as the
The VDC (video display controller), officially designated the VIC: screen memory, character memory, and attribute memory
8563, is a custom chip designed by Commodore's engineers (which corresponds to the VIC's color memory). However, all
especially to provide the 80-column display for the 128. The these elements for the VDC appear in a 16K block of memory
VDC provides a digital RGBI signal requiring a special moni- that is totally separate from the 128's system address space.
tor, but other than that the fundamentals of its video display This separate block is reserved solely for the VDC. Figure 8-16
are similar to those described for the VIC chip. The other illustrates the configuration of VDC memory.
thing that distinguishes the VDC from the VIC is the VDC's VDC screen memory holds screen code values identical to
high degree of programmability. Many of the features that are the screen codes for the VIC display. For each screen position,
fixed in the silicon of the VIC can be customized on the VDC the screen code serves as an index into character memory to
simply by storing a value in one of its registers. For example, select the pattern to be displayed in the position. All character
the VDC gives you complete control over the number of rows patterns are in RAM. The VDC has no character ROM of its
and columns in the screen display, and even over the number own, so the contents of the VIC's character ROM is copied
of pixels and scan lines in each character position. into VDC RAM during system initialization. Redefining char-
acters for the VDC is as simple as storing the new pattern in
Figure 8-16. VDC Memory Configuration the proper area of character memory. Each character definition
is 16 bytes long, but because the default character height is
S3FFF-
eight scan lines, only the first eight bytes are used to hold
character pattern information. The remaining eight bytes are
Lowerra se/uppercase generally padded with zeros. To determine the starting ad-
character set dress for the definition for any character, use the appropriate
formula from the following:
$3000-
for uppercase/graphics character set:
address = (screen code * 16) + 8192
Uppercase/graph ic
character set for lowercase/uppercase character set:
address = (screen code * 16) + 12288
$2000- The remaining memory area is attribute memory, which
determines the display characteristics for the character speci-
fied in screen memory. It is called attribute memory to distin-
Unused
guish it from simple color memory because each attribute
memory location specifies more than just the color. Figure 8-
$1000- 17 shows the use of each bit of attribute memory.
Attribute memory The lower four bits specify the foreground color for the
$0800- character in the corresponding screen position. Unlike the
VIC's color numbers, there is a strictly logical relationship be-
Screen memory tween the value in these bits and the resulting color. The RGBI
$0000- .
in Figure 8-17 stands for red, green, blue, and intensity. For ex-
ample, a value of %1000 in these bits selects only red, while
428
429
54784-54785 $D600-$D601 SD600 54784
Figure 8-17. VDC Character Attributes .^hich reverses the foreground and background pixels of the
character pattern. However, this attribute isn't used by the 128,
which instead has reversed character patterns as part of the stan-
R G B I dard character sets. Finally, bit 7 selects which of the two charac-
ter sets will be used. The VIC allows only one of the two
character sets to be used at any one time, but the VDC allows
color (see Table 8-5) ju to select the character set independently for each character
position.
character set
(0 «• uppercase/graphics) The register structure of the VDC chip is rather unusual. It
(1 = lowercase/uppercase) has only two registers visible in the normal system address
flash (0 = off, J = on) space. You must go through these registers to access any of the
internal functions of the VDC. Table 8-6 lists the VDC communi-
reverse cations registers visible to the processor. A detailed description of
(0 •" normal) underline (0 — off, 1 — on)
(1 = reverse) both locations follows.
%1011 selects red plus blue plus intensity, resulting in light Table 8-6. VDC External Communications Registers
purple. Table 8-5 shows the standard VDC color values. Note
that these values are different from the BASIC color numbers. 54784/$D600 VDC address/status register
54785/$D601 VDC data register
Table 8-5. Standard VDC Color Values
Value VDC color 54784 $D600 VDCADR
0/$00 black Address/status register
l/$01 dark gray (light black) The VDC actually has two different registers at this location: a
2/$02 dark blue write-only address register and a read-only status register. Any
3/$03 light blue value you store in this location goes to the address register.
4/$04 dark green The value specifies which one of the 37 internal VDC registers
5/$05 light green can be accessed via the data register at 54785/$D601. Since
6/$06 dark cyan only six bits are needed to specify all the valid register num-
7/$07 light cyan bers (0-36), bits 6 and 7 of the address register are unused
8/$08 dark red and have no effect when you are writing to this register.
9/$09 light red
10/$0A dark purple You can't read this location to determine which internal
ll/$0B light purple register is being accessed; reading always returns the status
12/$0C dark yellow register contents. The status register bits are defined as
13/$0D light yellow follows:
14/$0E light gray (dark white) Bits 0-2: These locations hold a constant number (like a ROM
15/$0F white location) indicating the version number of the VDC chip cur-
rently installed. There have been two versions of the VDC to
Bit 4 selects the flash attribute, causing the character in date. In early 128s, the value here will be %000 = 0, while in
the corresponding character position to blink at the rate speci- later models the value will be %001 = 1, The exact difference
fied in bit 5 of internal register 24/$18. Bit 5 selects the under- between the versions is not clear, but they do require slightly
line attribute, but the line can be moved to any scan line of different initialization. Specifically, internal register 25, the
the character position. Bit 6 controls the reverse attribute,
430 431
54784 $D600 &D601 54785
horizontal smooth scrolling register, requires different settings cation, a n d will return to %1 w h e n the specified register is
for the different versions. The IOINIT routine [$E109] checks ready for access. The s t a n d a r d procedure for reading from or
these VDC status register bits and performs the initialization writing to a VDC register is as follows;
accordingly. Reading: Writing:
LDX #register number LDX #register number
Bits 3-4: These bits are unused, and always return %0 when 5TX $D600
STX $D600
read. WAIT LDX $D600 WAIT LDX $D600
Bit 5: This bit, called the VBLANK flag, is used to indicate BPL WAIT BPL WAIT
when the VDC raster scan is in its vertical blank period. After LDA $D601 STA $D601
a full screen has been drawn and the electron beam has reached Refer to the entry below for information concerning the
the lower right corner of the display, the beam must be turned restrictions on accessing this location from BASIC.
off briefly while it is moved back to its home position in the
upper left corner to begin the next frame. Otherwise, moving 54785 SD601 VDCDAT
the beam would result in a diagonal line across the screen. Data register
The time while the beam is turned off for this repositioning is This register is the gateway to the internal registers of the
called the vertical blanking interval. This bit, normally %0, VDC. After you have set the desired internal register number
will be set to %1 during the vertical blanking period. by writing to the address register at 54784/$D600, the speci-
When you're programming special screen effects, it's fied register becomes visible at this location. Reading from this
handy to know when the blanking period is occurring. The location shows the internal register contents, and writing to
time when one frame has been completely drawn but another this location stores the value in the internal register. Once you
one has not yet been started is a good time to change screen specify an internal register, that register remains visible here
parameters without causing excessive flicker. The VIC chip can until you change registers by storing a new value in 54784/
generate a raster interrupt to signal when its vertical blanking $D600. Refer to the internal register descriptions below for
interval is beginning, but the VDC chip can't generate inter- more information on the effects of reading from and writing to
rupt requests, so this bit provides an alternate method of sig- the various registers.
naling that vertical blanking is in progress. Commodore's specifications for this chip state that when
Bit 6: This bit, known as the LP flag, is used to indicate when accessing the VDC, you should avoid machine language in-
new values have been latched in the internal light pen regis- structions that use the indirect addressing mode. That is, you
ters. Whenever a pulse is detected on the VDC chip's LP input should avoid using instructions like LDA ($CC),Y to read this
line, the row and column positions of the raster beam at that register because the VDC apparently responds improperly to
time are latched into internal registers 16—17/$10-$ll and such instructions. This imposes no particular hardship on ma-
this bit is set to % 1 . This bit will remain %1 until one or both chine language programmers, but has highly unfortunate con-
of the internal light pen registers are read, at which time it sequences for BASIC programmers. The 128's PEEK, POKE,
will be reset to %0. Thus, a %1 in this bit is a signal that a and WAIT instructions are implemented using the Kernal
new light pen position can be read from the internal registers, INDFET, INDSTA, and INDCMP routines, all of which use in-
while a %0 indicates that the register values have not changed direct-Y addressing to read or store values. As a result, you
since they were last read. See the entry for internal registers should not use PEEK, POKE, or WAIT statements to read or
16-17/$10-$ll for details of light pen reading. change the contents of this location or of location 54784/$D600.
Bit 7: This bit, known as the STATUS flag, is used to indicate This would seem to make the VDC inaccessible from
that the VDC is ready to read from or write to the internal BASIC. Fortunately, a pair of screen editor ROM routines pro-
vide a simple detour around this roadblock. In Chapter 7 they
'I register specified by writing to the external address register. are designated WRITEREG [$CDCC] and READREG [SCDDA],
The flag bit will be set to %0 when a value is stored in this Io-
432 433
54786-55039 $D602-$D6FF $D600-$D601 54784-54785
and they have the form shown above in the discussion of lo- VDC Internal Registers
cation 54784/$D600. To store a value in any VDC register Table 8-7 lists the various internal VDC registers which can be
from BASIC, use: accessed via the external communications register. A detailed
SYS DECCCDCC"), value, register description of each follows.
or
SYS 52684, value, register Table 8-7. VDC Internal Registers
where register is the number (0-36) of the internal VDC regis- 0/$00 Total number of horizontal character positions
ter you wish to access, and value is the value (0-255) you l/$01 Number of visible horizontal character positions
wish to place in that register. If you have used any other 2/$02 Horizontal sync position
BANK statements in your program, it would be wise to add a 3/$03 Horizontal and vertical sync width
BANK 15 statement before these SYS statements to insure the 4/$04 Total number of screen rows
proper memory configuration. 5/$05 Vertical fine adjustment
To read the contents of an internal VDC register from 6/$06 Number of visible screen rows
BASIC, use a statement of the form: 7/$07 Vertical sync position
8/$08 Interlace mode control register
SYS DECC'CDDA"),, register : RREG A 9/$09 Number of scan lines per character
or 10/$OA Cursor mode control
SYS 52698,, register : RREG A ll/$0B Ending scan line foT cursor
12/$0C Screen memory starting address (high byte)
Be sure you have two commas between the SYS address and 13/$0D Screen memory starting address (low byte)
the register number. After this statement has been executed, 14/$0E Cursor position address (high byte)
the variable A will contain the value read from the specified 15/$0F Cursor position address (low byte)
register. Again, if you change bank configurations elsewhere 16/$10 Light pen vertical position
in your program, it would be wise to add a BANK 15 before 17/$11 Light pen horizontal position
the SYS statement. 18/$12 Current memory address (high byte)
19/$13 Current memory address (low byte)
20/$14 Attribute memory starting address (high byte)
54786-55039 $D602-SD6FF 21/$15 Attribute memory starting address {low byte)
VDC chip register images 22/$ 16 Character horizontal size control register
Due to incomplete address decoding, images of the VDC chip 23/$17 Character vertical size control register
registers appear repeatedly through the remainder of this page 24/$18 Vertical smooth scrolling and control register
of memory. That is, storing a value in any even-numbered lo- 25/$19 Horizontal smooth scrolling and control register
cation in this range has the same effect as storing a value in 26/$lA Fore ground/background color register
54784/$D600, and storing a value in any location in this 27/$lB Address increment per row
range having an odd address has the same effect as storing a 28/$lC Character set address and memory type register
value in 54785/$D601. It might be easier to remember the ad- 29/$lD Underline scan-line-position register
30/$lE Number of bytes for block write or copy
dress of one of the image locations, such as 55000 in place of 31/$1F Memory read/write register
54784. Nevertheless, it's better programming practice to use 32/$20 Block copy source address (high byte)
the officially designated register addresses. 33/$21 Block copy source address (low byte)
34/$22 Beginning position for horizontal blanking
35/$23 Ending position for horizontal blanking
36/$24 Number of memory refresh cycles per scan line
434 435
54784-54785 SD600-SD601 AP600-$D601 54784-54785
436 437
54784-54785 $D600-$D601 6D600-$D601 54784-54785
mine which system is being used (since the VIC isn't pro- 6 $06
grammable like the VDC, there is a different version of the Number of visible screen rows
VIC for each of the two video systems). This register is then The value in this register determines how many of the vertical
initialized accordingly: to 32/$20 for NTSC systems or 39/$27 character positions specified in register 4/S04 can actually be
for PAL systems, selecting 33 or 40 rows, respectively. Since used to display characters. The value here must be less than
the default character-position height is eight scan lines, the re- the total number specified in register 4/$04. The default value
spective total heights are 33 * 8, or 264 lines, for NTSC, and established for this register by the Kernal IOINIT routine
40 * 8, or 320 scan lines, for PAL. These scan-line totals [$E109] is 25/$19, which sets up the standard 25-row display.
should remain constant, so if you increase the character height One obstacle to selecting other numbers of rows is that the
you must decrease the total number of rows, and vice versa. screen editor ROM routines will, by default, assume a 25-line
screen. When decreasing the number of rows, you can make
5 $05 the screen editor use the reduced number by storing a value
Vertical fine adjustment equal to the new number of rows minus 1 in location 237/
Bits 0-4: The total number of scan lines in the VDC's video $ED, then resetting the output window to full screen size (by
display should be 264 for an NTSC (North American) system printing two cursor-home characters, for example). The screen
or 320 for a PAL (European) system. The number of scan lines editor routines will not support a display with more than 25
used in the VDC display is given by the total number of verti- rows, so you'll have to provide your own character manipula-
cal positions (specified in register 4/S04) multiplied by the tion routines to use such a screen.
number of scan lines per character position (specified in regis-
ter 9/$09). If the result doesn't come out exactly equal to the 7 $07
required 264 or 320, the VDC can add a few extra scan lines at Vertical sync position
the end to achieve the proper result. The value in this register The value in this register determines the vertical character po-
specifies the number of extra scan lines to add. The available sition at which the vertical sync signal will be generated. This
five bits allow up to % 11111 = 3 1 / $ i F additional scan lines. register can be used to adjust the vertical location of the active
The default character height of eight scan lines is an exact display area within the screen. The default value for this regis-
multiple of both 264 and 320 (33 * 8 = 264 and 40 * 8 = ter, established by the IOINIT routine [$E109], is 29/S1D for
320). Thus, no extra scan lines are required, so this register is NTSC (North American) systems or 32/S20 for PAL (Euro-
initialized to 0/$00 by the Kernal IOINIT routine [$E109]. As pean) systems. Decreasing the value here will move the active
an example of the use of this register, assume that you in- display area down the screen, while increasing the value will
creased the character height to nine scan lines. For an NTSC move the active display area upwards. However, you should
system, 264 / 9 = 29 with a remainder of 3. Thus, for this not increase the value here above the maximum number of
case you should specify 29 for the total number of vertical rows specified in register 4/$04.
character positions and store a 3 in this register to provide the
required additional scan lines. 8 $08
Bits 5-7: These bits are unused; writing to them has no effect, Interlace mode control
and they always return %1 when read. Thus, the value you Bits 0-1: The value in these bits controls the interlace mode of
read from this register will always be at least 224/$E0. To the screen. The complete standard for NTSC video calls for a
mask off these bits and see only the valid bits of the register, frame (raster) of 525 lines to be redrawn 30 times per second,
use AND 31 in BASIC or AND #$1F in machine language. while the PAL standard calls for 625 lines redrawn 25 times
per second. The full screen isn't drawn all at once; instead, it's
drawn in two passes with half the lines for the frame drawn
on each pass. The lines for the second pass of the frame are
439
54784-54785 $D600-$D601
$D600-$D601 54784-54785
drawn between the lines for the first. Like most computer dis-
plays, the VDC normally takes a shortcut and draws half the screen will not support a display longer than 25 lines, so
full number of lines at twice the rate. This noninterlaced dis- you'll have to write your own text manipulation routines to
play provides sufficiently sharp output for most uses. How- handle the extra 25. Nevertheless, this mode has interesting
ever, the VDC is also capable of producing two interlaced possibilities.
display modes. The modes are selected as follows: Bits 2-7: These bits are unused; writing to them has no effect,
Bits and they always return %1 when read. Thus, the value you
I 0 Value Interlace mode read from this register will always be at least 252/$FC. To
x 0 0 or 2 noninterlaced mask off these bits and see only the valid bits of the register,
0 1 1 interlaced sync use AND 3 in BASIC or AND #$03 in machine language,
II 3 interlaced sync and video
The default value is 0/$00, which selects the standard 9 $09
noninterlaced mode. The system never uses any other mode. Total number of scan lines per character
In the interlaced sync mode, the number of scan lines is dou- Bits 0-4: These bits determine the total vertical height (in scan
bled. Each horizontal scan line is drawn twice, once on the lines) of each character position. The value stored here should
first pass and very slightly lower on the second pass. The re- be one less than the desired number of scan lines. The total
sult should be greatly improved vertical resolution, but you'll vertical height value includes the scan lines for the active por-
probably be disappointed. Remember that each tiny dot on the tion of each character position, plus any desired number of
screen glows only very briefly after being struck by the raster blank scan lines for intercharacter vertical spacing. The height
video beam. Since this mode must draw twice as many lines, of the active portion of the character position is determined by
it draws each line only half as often. On most video monitors, the value in register 23/$17.
the first set of lines will have started to fade before the second The default value for this register, established during the
set is completely drawn. As a result, the screen will appear to IOINIT routine [SE109], is 7/$07, for a total character-position
jitter annoyingly in this mode. height of eight scan lines. In this case, there will be no vertical
The remaining choice is interlaced sync and video mode. intercharacter spacing because this is less than the active char-
In this case, the VDC also draws twice as many lines as non- acter height. (In the default character set, intercharacter spacing
interlaced mode, but the alternating half-frames are indepen- is achieved by leaving the bottom row of the character pattern
dent, so you can use twice as many horizontal lines per frame blank.) The five available bits allow values up to %11111 =
(the maximum screen height in scan lines is double that of the 31/$IF, for character-position heights of up to 32 scan lines.
noninterlaced mode). This creates the tantalizing prospect of However, when changing this value to allow for greater verti-
an 80-column X 50-line text screen. The following routine cal resolution, you must keep in mind that the value here mul-
sets up such a display: tiplied by the total number of rows specified in register 4/$04
(and plus the number of extra scan lines specified in register
10 WR=DEC("CDCC") 5/$05) determines the number of scan lines in the display.
20 SYS W R , 3 , 8 This total should always be 264 lines for NTSC (North Ameri-
30 SYS WR,64,4 can) systems or 320 lines for PAL (European) systems.
40 SYS W R , 5 0 , 6 The value here also determines how much memory is re-
50 SYS WR,58,7 quired for character pattern memory. While the value here is
60 SYS W R , 1 2 8 , 0
less than or equal to 15 (while the character height is 16 or
fewer scan lines), each character pattern is allocated 16 bytes.
However, this setup does have limitations. It suffers from the
Since the VDC supports two complete 256-character sets, a to-
same jitter problems as the other interlaced mode. Further-
tal of 512 * 16, or 8192 bytes, are required for character mem-
more, the screen editor routines that control printing to the
ory' However, if the character height exceeds 16 scan lines (if
440
441
54784-54785 $D600-$D601 $D600-$D601 54784-54785
the value here is greater than 15), then 32 bytes are allocated
for each character pattern. In this case, 512 * 32, or 16,384 Bit values Cursor mode
bytes, are required for character memory. Note that this is all 0/$00 solid {nonblinking) cursor
the memory available to the VDC. 32/S20 no cursor
Bits 5-7: These bits are unused; writing to them has no effect, 64/$40 blinking at 1/16 screen refresh rate
and they always return %1 when read. Thus, the value you 96/$60 blinking at 1/32 screen refresh rate
read from this register will always be at least 224/$E0. To
mask off these bits and see only the valid bits of the register, The default setting for these bits is %11, specifying a cursor
use AND 31 in BASIC or AND #$1F in machine language. blinking at the slower of the two rates. The operating system
also supports a nonblinking cursor, selected by printing ESC E
10 $0A [$CB0B]. In this case, the bits are changed to %00. To rum the
Cursor mode control cursor off when the system is not accepting input (as when a
program is running), these bits are reset to %01 [$CD9F].
The value in this register cannot be changed directly while the
standard screen editor ROM routines are used for printing. Bit 7: This bit is unused; writing to it has no effect, and it al-
The contents of a shadow location at 2603/$OA2B are copied ways returns %1 when read. Thus, the value you read from
to this register each time the cursor position is updated. Thus, this register will always be at least 128/$80. To mask off this
to change the value in this register, you must store the desired bit and see only the valid bits of the register, use AND 127 in
value in the shadow location rather than in the register. BASIC or AND #$7F in machine language,
Bits 0-4: The value in these bits determines the scan line
within each character position for the top of the cursor. Scan 11 $0B
lines within character positions are numbered beginning with Bottom scan line for cursor
0 for the top line of the position. Bits 0-4 of register ll/$0B Bits 0-4: These bits determine the scan line within a character
determine the bottom line, and together these registers deter- position for the bottom of the cursor. Together with bits 0-4
mine the height of the cursor. The available five bits allow of register 10/$0A, this serves to determine the height of the
starting row numbers as large as %11111 = 31/$1F. The de- cursor. The value here should be one greater than the desired
fault value for these bits is %00000, to start the cursor at char- bottom scan line (scan-line numbering starts with 0 for the top
acter scan line 0, the top line of the character, for the standard scan line of the character position). The five available bits
full-height block cursor. The operating system also supports allow values up to % 11111 = 31/$1F, so the cursor can go as
an underline cursor, selected by printing ESC U [$CAFE], In low as scan line 30, However, the actual displayed cursor
this case, the value here is changed to %00111 (7) to start the height will never be greater than the character-position height
cursor on the bottom line of the standard character position. specified in register 9/$09. The default value for this register,
The value for the top scan line should be no greater than the established by the IOINIT routine [$E109], is 7/$07, so the
maximum number of scan lines specified in register 9/$09, or normal bottom scan line of the cursor is scan line 6 of the
else the cursor will not be visible. character position.
Bits 5-7: These bits are unused; writing to them has no effect,
Bits 5-6: These bits control the type of cursor provided. Unlike and they always return %1 when read. Thus, the value you
the VIC, where the cursor is an effect maintained by software,
the VDC has hardware to generate a cursor automatically. The read from this register will always be at least 224/$E0, To
possible modes are as follows: mask off these bits and see only the valid bits of the register,
use AND 31 in BASIC or AND #$1F in machine language.
442
443
54784-54785 $D600-$D601 _ _ _
444 445
54784-54785 $D600-$D601 $D600-$D601 54784-54785
that if you position the pen slightly below the bottom screen
line you can get a reading of 26/S1A. 18 §J2
While the vertical resolution is good, the horizontal reso- 19 $13
lution is quite poor. The horizontal reading won't correspond Current memory address
to the row number (1-80). Instead, it corresponds approxi- This register pair specifies which address in the VDC's private
mately to the absolute horizontal character position, which in- block of RAM will be referenced by the next read or store op-
cludes the border areas on the left and right edges of the eration involving register 31/S1F. As with the other VDC ad-
screen. You should find that when the pen is pointed at the dress register pairs, the first register (18/$12) holds the high
leftmost character position, you get a reading of about 27-29 byte of the address and the second (19/$13) holds the low
in register 17/$11. This implies that the rightmost character byte. A value stored in register 31/$1F is transferred to the
position should give readings of about 106-108. Actually, you VDC memory location specified in this register pair. Reading
may get higher readings—120 or more. In fact, even if you register 31/$1F returns the value in the location in VDC mem-
hold the pen perfectly stil] you may see the character position ory with the address specified in this register pair. For copy or
vary up or down by 4 or 5. The moral is that the light pen is fill operations, the value in these registers determines the des-
much better at reading vertical than horizontal positions. tination address for the operation. These registers are auto-
You'll have better luck if you limit yourself to checking incrementing, meaning that the address value here is auto-
whether the pen is within a range of horizontal positions. For matically increased by 1 after each read or store to register
example, if you read the horizontal position and store the re- 31/S1F. Thus, when you wish to read or load a continuous se-
sult in the variable H, then an expression such as H = INT({H ries of VDC memory locations you only need to set the mem-
— 30) / 8) will return a range of values 0-9 indicating ory address in these registers before the first read or store.
roughly which one of ten eight-column horizontal areas the After that, you can just read from or write to register 31/$1F
pen is pointing to. and the address will be handled automatically.
You should be aware that these registers can be tricked 20 $14
into reading false values. Pin 6 of control port 1 is also used 21 $15
for light pen input for the VIC chip, and a light pen signal Starting address for attribute memory
generated on the 40-column screen will latch meaningless val-
When attributes are activated, this register pair determines the
ues in these registers. In lieu of a light pen, several other
starting address for attribute memory, the area which holds
events can cause a pulse on the LP line. That control port pin
attribute values for each active character position on the
is also used for the joystick fire button, so pressing the button
screen. (Attributes can be turned on and off by setting bit 6 of
of a joystick plugged into port 1 will also latch values in these
register 25/$19.) The size of the attribute memory area de-
registers. Because of this joystick button function, the port line
pends on the number of active rows and columns specified in
is also connected to the line from row 4 of the keyboard matrix.
registers 2/$02 and 6/$06, and will be the same as the size of
This has two consequences. First, pressing any of the follow-
the screen memory area. See the discussion of attributes in the
ing keys with no light pen connected will latch meaningless
introduction to this section for more information.
values: Fl, Z, C, B, M, period, right SHIFT, space, the 2 and
These locations are initialized to 2048/S0800, the default
ENTER keys on the numeric keypad, and the ^ key in the
starting address for attribute memory. Like the other address
cursor group. More significantly, while a light pen is con-
pairs in the VDC, the first register (20/$14) holds the high
nected, all of these keys will be "dead," and cannot be typed.
byte and the second (21/$15) holds the low byte. Attribute
memory can start at any address within the VDC's address
space. Even if you change the value here, the screen editor
ROM routines will continue to assume that attribute memory
446 447
_
54784-54785 $D600-$D601 SP600-$D601 54784-54785
is in its default position unless you also change the value in available five bits allow you to specify values up to % 11111
the attribute starting-page pointer at 2607/$0A2F. = 31/$1F. If the value here is less than the total number of
scan lines for the character position, the extra lines will be
22 $16 blank for intercharacter spacing. If the value here is greater
Character horizontal size control than the total number of scan lines, only the total number of
Bits 0-3: The value in these bits determines how many of the scan lines will be displayed. For graphic mode, the value here
total horizontal pixels in the character position will be used to should be at least equal to the total number of scan lines (the
display character pattern data. (The total number is specified value in register 9/$09 plus 1); otherwise there will be gaps in
in bits 4-7 of this register.) If the number of active pixels is the display.
less than the total number of pixels, the extra pixels will be The default value stored in this register is 8/$08, for eight
blank for intercharacter spacing. If you specify a value here active scan lines per character position. This is equal to the de-
that is greater than the total number of pixels available for the fault total number of scan lines for the position, so there will
position, only the specified total number of pixels will be visi- be no intercharacter spacing. (For the standard character set,
ble. However, the value here should not exceed 8, since a intercharacter spacing is achieved by leaving the bottom row
maximum of eight bits are available per byte of character pat- of most character definition patterns blank.)
tern data. Even for values greater than 8, no more than eight Bits 5-7: These bits are unused; writing to them has no effect,
pixels will be active per horizontal scan line within the charac- and they always return %1 when read. Thus, the value you
ter position. For graphic mode, the value here should be equal read from this register will always be at least 224/$E0. To
to the total number of pixels; otherwise there will be gaps in mask off these bits and see only the valid bits of the register,
the display. use AND 31 in BASIC or AND #$1F in machine language.
The default value for these bits is 8, for eight active hori-
zontal pixels per character-position scan line. This is the same 24 $18
as the total number of pixels per position, so there will be no Vertical smooth scrolling and control
intercharacter spacing. (For the default character set, the Bits 0-4; These bits can be used to smoothly scroll the screen
rightmost column of each character pattern is left blank to pro- vertically upward. The value here specifies the number of scan
vide the effect of intercharacter spacing,) lines the display should be shifted upward. Although five bits
Bits 4-7: The value in these bits determines the width of each are available, the value here should not exceed the value in
character position (in pixels). The value stored here should be register 9/$09.
one less than the desired total number of pixels. If the total is Bit 5: This bit controls the blinking rate for all characters on
greater than the number of active pixels specified in bits 0-3 the screen with the flash attribute. A character position has the
of this register, the extra pixels will be blank for intercharacter flash attribute when bit 4 of its corresponding attribute mem-
spacing. The default value for these bits is 7, for eight total ory is set to % 1 . The two available blinking rates are once
pixels per character position. The total number of horizontal each 16 times the screen is refreshed (selected when this bit is
pixels is determined by multiplying the value here (plus 1) by set to %0) or once each 32 times (selected when this bit is set
the total number of character positions (from register 0/$00). to %l). For NTSC (North American) systems, the screen is re-
drawn 60 times per second, so the corresponding blinking
23 $17 rates are about four times per second when the bit is %0 and
Character vertical size control about twice per second when the bit is % 1 .
Bits 0-4: The value in these bits determines how many of the The default setting for this bit is % 1 , for the slower blink-
total scan lines for each character position (specified in register ing rate. This is established during the IOINIT routine [$E109],
9/$09) will be used to display character pattern data. The
448 449
54784-54785 $D600-$D601 $D600-$D601 54784-54785
part of both the reset and RUN/STOP-RE STORE sequences. each pixel is twice as large, there will be room for only half as
This setting is not changed by any other ROM routine. many on the screen. Thus, you must reduce the values in the
Bit 6: This bit controls a special VDC feature known as reverse horizontal screen width registers (0-2/$00-$02) to half their
mode. While this bit is %0, all pixels on the screen repre- normal values. The following routine sets up a VDC 40-column
sented by %0 bits in character patterns or the graphic screen display that will be very similar to the VTC's 40-column display:
bitmap take the background color specified in bits 0-3 of reg-
ister 26/$lA, and all pixels represented by %1 bits take the 10 WR=DEC("CDCC"):RR=DEC("CDDA")
foreground color specified in a corresponding attribute mem- 20 SYS WR,63,0:SYS WR,40,1:SYS WR,55,2
30 SYS RR,,25:RREG A:SYS WR,(A OR 16),25
ory location (or in bits 4-7 of register 26/$lA if attributes are 40 SYS WR,(8*16)+9,22
disabled). Setting this bit to %1 reverses the color sources, so 50 SYS WR,40,27
that all pixels for %0 bits take the foreground color and all 60 POKE 238,39
pixels for %1 bits take the background color. 70 PRINT"{2 HOMEllCLR}"
This bit is initialized to %0 for a normal screen display.
Bit 5: This bit controls a special VDC feature called
The screen editor ROM supports escape sequences to change
semigraphic mode. When semigraphic mode is activated
this bit. The ESC R sequence will set the bit to % 1 , reversing
(when this bit is %1), the rightmost active pixel will be re-
the screen display. The ESC N sequence will clear the bit to
peated through the intercharacter spacing pixels. For this
%0, returning the display to normal.
mode to have any visible effect, there must be some
Bit 7: This bit determines whether the next block operation intercharacter spacing (the value in bits 0-3 of register 22/$16
initiated by writing to register 3O/$1E will be a copy or a fill. must be less than the total number of pixels specified in bits
Setting this bit to %0 specifies a fill operation, while setting it 4-7 of that register). This mode has no effect in graphic mode.
to %1 specifies a copy operation. See the entry for register One use of this mode is to create a simple "digital" character
3O/$1E for more information on VDC block operations. This effect. Try these lines:
bit is set to %0 when the register is initialized during the SYS 52684,118,22
IOINIT routine [$E109]. SYS 52698,,25: RREG A: SYS 52684,(A OR 32),25
25 $19 Bit 6: The VDC has two methods of supplying foreground
information for its display. When this attribute enable bit is set
Horizontal smooth scrolling and control
to % 1 , each character position will have a corresponding
Bits 0-3: These bits can be used to smoothly scroll the screen attribute memory location. Refer to the introduction to this
horizontally. The use of these bits depends on the version of section for details on attributes. The starting address of attribute
the VDC in your 128. (The version number can be determined memory is determined by the value in registers 20-21/$14-
by reading bits 0-2 of the external communications register at $15, When this bit is %0, attribute memory is not used. In-
54784/$D600.) For version 1 of the VDC, which includes most stead, all character positions take the foreground color specified
128s, this register should be initialized to the maximum char- in bits 4-7 of register 26/$lA. In this case, the character posi-
acter width (in bits 4-7 of register 22/$16). Each decrement of tions cannot have the flash, underline, or reverse attributes,
this register shifts the display one pixel to the left. For the and only the first of the two character sets will be available.
older version 0 of the VDC, these bits should be initialized to
%0000. In this case, each increment of these bits shifts the dis- Bit 7: This bit determines whether the VDC will operate as a
play one pixel to the right. text or graphics display. Text mode, selected when the bit is
Bit 4: This bit controls the VDC's pixel double feature. While set to %0, is the only one supported by the 128 operating sys-
this bit is %0, pixels will be their normal size. Setting this bit tem (%0 is the default value for this bit). In that mode, each
to %1 will double the size of all horizontal screen pixels. Since screen memory position holds a screen code which serves as
450 451
54784-54785 $D600-$D601 $D600-$D601 54784-54785
an index into character memory to specify the pattern to be program 8-1. 80-Column Sketchpad
displayed in that position.
When this bit is set to % 1 , graphics mode is selected. In 100 GRAPHIC 0:FAST
that mode, screen memory is replaced with a bitmap. (There is 110 WR=DEC("CDCC"):RR=DEC("CDDA")
no cursor on the graphic display.) Each bit in the bitmap con- 120 SYS RR,,25:RREG A:SYS WR,(A AND 63)OR 128,25
trols the state of one pixel in the display. The layout of the 130 SYS RR,,24:RREG A:SYS WR,A AND 127,24
bitmap is much simpler than that for'the VIC screen. Each 140 SYS WR,0,13:SYS WR,0,19:SYS WR,0,31
150 FOR 1=0 TO 63:SYS WR,255,30:NEXT 1
horizontal scan line is controlled by a sequential series of 160 X=320:Y=100:BC=0:FC=15
bytes. The size of the bitmap (in bytes) is determined by the 170 GET KS:ON INSTR( "BF{HOME HCLR j " , KS ) GOTO 180,1
number of active horizontal positions times the number of ver- 80,160,140:GOTO 190
tical positions times the number of scan lines per vertical posi- 180 BC={BC-(K?="B"))AND 15:FC=(FC-(K$="F"))AND 15:
tion. For the standard screen setup, this means that 80 * 25 * SYS WR,FC*16+BC,26
8, or 16,000 bytes, are required—almost all of the available 190 D=JOY(2) AND 15:IF D=0 THEN 170
200 Y=Y+(D<3 OR D=8)-(D>3 AND D<7);IF Y<0 THEN Y=l
VDC memory. At eight pixels per byte, there are 128,000 indi- 99:ELSE IF Y>199 THEN Y=0
vidual pixels on the graphic display. 210 X=X-(D>1 AND D<5)+{D>5):IF X<0 THEN X=639:ELSE
The graphic display can use attribute memory for color IF X>639 THEN X=0
information. In this case, the relationship of attribute locations 220 AD=(Y*80)+INT(X/8):AH=INT(AD/256):AL=AD-(AH*25
to bitmap positions is similar to that for the VIC screen. Each 6)
attribute memory location controls the color for all pixeis 230 SYS WR, AH ,18:SYS WR,AL,19
240 SYS RR,,31:RREG A
within a character-position area on the screen. However, there 250 SYS WR,AH,18:SYS WR,AL,19
isn't enough free memory available for a full bitmap and a full 260 SYS WR,A OR 2T(7-(X AND 7)),31
attribute memory area. One solution is to turn off attributes 270 GOTO 170
(set bit 6 of register 25/$19 to %0). This limits all screen posi-
tions to the same foreground and background colors (as speci- the same foreground and background colors). The CLR/
fied in register 26/$lA). The other solution is to reduce the HOME key can be used to move the drawing point back to its
size of the active screen area to free up enough memory for an home position in the center of the screen, and SHIFT -
attribute area. For example, if you reduce the number of active CLR/HOME will clear the display.
rows to 22, then 80 * 22 * 8, or 14,080 bytes, will be required
for the bitmap, and 80 * 22, or 1760 bytes, will be required for 26 $1A
attribute memory, so there will be enough room within VDC Background and foreground colors
memory for both bitmap and attributes. Bits 0-3: The value in these bits determines the background
When attribute memory is enabled for a graphic display, color of the display. For text mode, this is the color of all
the lower four bits of each attribute memory location deter- pixels represented by %0 bits in the pattern definition for the
mine the color of all foreground (%1) pixels in the correspond- character in each screen position. For graphic mode with
ing character-position area, and the upper four bits determine attribute memory disabled, the value here determines the color
the color of all background (%0) pixels in the character °f all pixels represented by %0 bits in the bitmap. The cor-
position. respondence between register value and background color is
as shown in Table 8-5. For graphic mode with attribute mem-
Program 8-1 is a very simple example of a bitmapped ory enabled, the value here determines the color of the screen
drawing program for the VDC. Use a joystick in port 2 to border only.
sketch. Pressing the B key will change the background color
and pressing the F key will change the foreground color The default background color value, 0/$00 (black), is es-
(attribute memory is turned off, so all character positions use tablished by the Kernal IOINIT routine [$E109], part of both
the reset and RUN/STOP-RESTORE sequences. From BASIC,
452 453
54784-54785 $D600-$D601 $D600-$D601 54784-54785
the background color can be changed using the statement Bit 4: This bit specifies the type of RAM chip used for VDC
COLOR 6, color number. However, the values for the color num- video memory. When the bit is %0, the VDC is configured for
ber parameter are not the same as the color values shown in 4416 chips (16K X 4 bits). When the bit is % 1 , the VDC is
Table 8-5. Refer to the description of the COLOR statement in configured for 4164 chips (64K X 1 bit). Since the 16K VDC
the System Guide that came with your 128 for more information. video memory space in the 128 is provided by two 4416 chips,
this bit is initialized to %0 by the Kernal IO1NIT routine
Bits 4-7: When attributes are disabled (by setting bit 6 of reg- [$E109]. It is theoretically possible to replace the existing chips
ister 25/$19 to %0), the value in these bits specifies the fore- with the 64K variety to quadruple the amount of available
ground color for the display. For text mode, this is the color VDC RAM. However, the swap involves unsoldering the exist-
for all pixels represented by %1 bits in the pattern definitions ing chips from the circuit board and soldering the new ones in
for all screen positions. For graphic mode, the value here de- their place. This is not a task for the inexperienced, and will
termines the color of all pixels represented by %1 bits in the most certainly void any warranty on your 128.
bitmap. For either mode, if the screen is switched to reverse Bits 5-7: These bits determine where within VDC memory the
mode (by setting bit 6 of register 24/S18), the value here will character pattern definitions will be located. The amount of
instead determine the color for all pixels represented by %0 memory required for the character set depends on the value in
bits in the character pattern or bitmap. The correspondence register 9/$09. If the character height is 16 or fewer scan lines,
between bit values and colors is as shown in Table 8-5. each character set requires 4K (4096 bytes). Character heights
of 17-32 scan lines require 8K (8192-b'yte) character sets. The
27 $1B VDC normally supports a pair of character sets, using bit 7 of
Address increment per row of characters the attribute memory location to select between them for each
The value in this register will be added to the value in register character position. Thus, 8K is normally used for character sets
1/S01 to determine the amount by which to increase the screen when the character height is 16 or fewer scan lines, and 16K is
memory address for each new row of the display. This allows used when the character height is greater than 16 scan lines.
you to set up a virtual screen wider than the actual screen. In the latter case, bit 5 is not used in the address selection.
You can scroll back and forth across the virtual screen by ad- The possible starting addresses for character patterns are as
justing the screen starting address in registers 12-13/$0C-$0D. follows (the asterisks indicate valid selections for 16K-character
The default value for this register is 0/$00, since no extra set pairs):
columns are used with the 80-column text display. The screen Bits Character memory
editor routines that support printing to the VDC screen all as- 7 6 5 starting address
sume an 80-column screen line. If you reduce the number of 0 0 0 0/$0000 *
active columns in register l/$01, you should increase the value 0 0 1 8192/$2000
in this register correspondingly so that the total remains 80. 0 1 0 16384/$4000 *
0 1 1 24576/$6000
28 $1C 1 0 0 32768/$8000 *
Character pattern address and memory type 1 0 1 40960/SAOOO
110 39152/SC0O0 *
Bits 0-3: These bits are unused; writing to them has no effect, 1 1 1 57344/$E000
and they always return %1 when read. Thus, the value you
read from this register will always be at least 15/SOF. To mask Since the 128 has only 16K of RAM for the VDC, only the
off these bits and see only the valid bits of the register, use first two settings are currently valid. (Note that there is insuffi-
AND 240 in BASIC or AND #$F0 in machine language. cient room in the 128's 16K of VDC video memory for a 16K
character set plus screen and attribute memory.) These bits are
initialized to %001 by the IOINIT routine [$E109], part of the
454 455
6n600-$P601 54784-54785
54784-54785 $D600-$D601
reset and RUN/STOP-RESTORE sequences, so the default or a fill. The operations require different preparatory steps, as
character set starting address is 8192/$2000. Since this area is outlined below:
RAM, not ROM, it is necessary to copy character patterns into For a fill operation:
this area of memory if the VDC is to display recognizable 1. Set bit 7 of register 24/S18 to %0 to indicate a fill
characters. This step is performed during the IOINIT routine operation.
by calling the screen editor INIT80 routine [$CE0C]. 2. Load registers 18-19/$12-$13 with the starting address of
the area to be filled (the destination area).
29 $1D 3. Store the value with which the area is to be filled in register
Underline scan-line control ' 31/$1F. This will fill the first location.
Bits 0-4: The value in these bits determines which scan line 4. Store the number of bytes to be filled, minus one because of
within the character position will be filled for any characters the store performed in step 3, in register 3O/$1E. This will
with the underline attribute. (A character position has the un- initiate the block fill operation.
derline attribute when the corresponding attribute memory po- For a copy operation:
sition has bit 5 set to %1.) Since the line can appear on any 1. Set bit 7 of register 24/$18 to %0 to indicate a fill operation.
horizontal scan line of the character position, it's not strictly
2. Load registers 18-19/$12-$13 with the starting address of the
correct to call it an underline. For example, you could move
the line to the top line of the position to be an overbar, or to area to be filled (the destination area).
the middle line of the position to serve as an overstrike. Scan 3. Store the value with which the area is to be filled in register
line 0 is the top line of the character position. The available 31/$1F. This will fill the first location.
five bits allow a maximum scan-line value of %11111 = 3 1 / 4. Store the number of bytes to be filled, minus one because of
$1F. However, the underline will not be visible if the value is the store performed in step 3, in register 3O/$1E. This will ini-
greater than the maximum character-position height in bits tiate the block copy operation.
4-7 of register 22/$16.
Either operation can be performed repeatedly to copy or
Bits 5-7: These bits are unused; writing to them has no effect, fill areas larger than 255 bytes. The destination address regis-
and they always return %1 when read. Thus, the value you ters (18-19/$12-$13) and, for copy operations, the source ad-
read from this register will always be at least 224/$E0. To dress registers (32-33/$20-$21) increment automatically each
mask off these bits and see only the valid bits of the register, time a location is copied or filled, so upon completion of one
use AND 31 in BASIC or AND #$1F in machine language. copy or fill operation they will hold the address of the first
byte beyond the area affected by the copy or fill. Thus, it is
30 $1E not necessary to reload the address registers to copy or fill
Number of bytes to copy or fill more subsequent memory locations, nor is it necessary to set
The VDC has the capability to copy blocks of data up to 255 the operation flag or to load the data register after the first
characters long from one area of VDC memory to another, and block. (For multiple fill operations, the instruction above to
to fill areas up to 255 bytes long with a specified value. The subtract 1 from the desired number of bytes to fill applies only
value in this register determines the number of bytes to be for the first block.)
copied or filled. The copy or fill operation begins immediately
after the count value is stored here. The setting of bit 7 of reg- 31 $ 1 F
ister 24/$18 determines whether the operation will be a copy Memory read/write
This register is the gateway between the VDC's private block
of RAM and the rest of the 128 system. When read, this
457
456
54784-54785 $D600-$D601 fiP600-$D601 54784-54785
location reflects the contents of the VDC memory location ad- The value in register 34/$22 must be less than the value
dressed in registers IS—19/$12—$13. Writing a value to this in register 0/$00; otherwise, the entire display will be
register will cause the value to be transferred to the location blanked. The value in 34/$22 here must also be greater than
addressed in registers 18—19/$12—13. For both reading and the value in register 35/$23 to prevent an entirely blank dis-
writing, the address in registers 18-19/$12-$13 will automati- play. The default values for these locations are 125/S7D and
cally be incremented after this register is accessed. Thus, to 100/$64, respectively. This positions the blanking interval en-
read or write a sequential series of locations you need only tirely outside the active screen area. For purposes of blanking
load the starting address of the series into registers 18—19/ an area of the screen, a value of 6/$06 in these registers corre-
$12—$13. You can then read or write repeatedly to register sponds to the leftmost column of the standard screen and a
31/$1F; the destination address will automatically increment value of 85/$55 corresponds to the rightmost column.
after each read or write.
32 $20 36 $24
Number of memory refresh cycles per scan line
33 $21 Bits 0-3: The value in these bits determines the number of
Source address for block copy memory refresh cycles per scan line. The RAM chip used for
The VDC has the capability to copy blocks of data up to 255 the VDC's video memory is a type known as dynamic RAM.
bytes long from one area of memory to another (see the entry A dynamic RAM can hold data only briefly without external
for register 3O/$1E for details). The value in this register pair support. Just as the image on the video screen must be con-
determines the source address for copy operations, the address stantly redrawn to keep it from fading away, dynamic RAM
from which data will be copied. Like all other address register must be constantly refreshed to keep it from losing its con-
pairs in the VDC, the first register (32/$20) holds the high tents. The VDC handles this refresh function automatically for
byte of the address and the second (33/$21) holds the low its video RAM, just as the VIC automatically handles the re-
byte—the opposite of the normal 8502 address format. The freshing of system RAM. However, for the VDC, the number
registers should be loaded with the desired source starting ad- of refresh cycles provided during each scan line is programma-
dress before the copy operation is initiated. Upon completion ble. The IOINIT routine [SE109] initializes these bits to %0101
of the operation, the registers will hold the address of the next for five refresh cycles per scan line, and there's no reason to
location beyond the last one involved in the operation. Thus, change that setting.
it is possible to copy blocks of more than 255 successive bytes
by using repeated copy operations without reloading these Bits 4-7: These bits are unused; writing to them has no effect,
registers. and they always return %1 when read. Thus, the value you
read from this register will always be at least 240/SFO. To
34 $22 mask off these bits and see only the valid bits of the register,
35 $23 use AND 15 in BASIC or AND #$0F in machine language.
Horizontal blanking positions
37-63 $25-83F Unused
The VDC can adjust its horizontal blanking interval to blank a
portion of the screen. These locations control the horizontal Since the external address register at 54784/$D600 allows a
width and position of the blanked area. If the blanked area ex- six-bit register number, these register addresses can also be
tends onto the active portion of the screen, any text under the specified. However, none of these internal registers are used,
blanked area is only covered, not erased. The value in register and writing to them has no effect. All register numbers in this
34/$22 determines the rightmost blanked column, and the range return the value 255/$FF when read.
value in register 35/$23 determines the leftmost blanked col-
umn. The blanked area extends the entire height of the screen.
458
459
55040-55295 $D700-$D7FF fen800-$DBFF 55296-56319
460 461
55296-56319 $D800-$DBFF anH00-$DBFF 55296-56319
character positions. Multicolor mode must be selected on a po- multicolor bitmapped screen can be thought of as a grid of 4
sition-by-position basis. For each position, bit 3 of the color X 8-pixel blocks that is 40 blocks across and 25 blocks tall.
memory location for that position specifies whether the position Each block of dots in the grid has a corresponding color mem-
will behave like standard character mode or multicolor mode. ory location. The color of dots within the block which have
Setting bit 3 of a color memory location to %0 will make the same bit pattern is not independently selectable—all dots
the position behave as if standard character mode were still with %11 bit patterns within the same 4-dot X 8-line block
active for that position, except that only bits 0-2 of the color take the same color, the one specified in the color memory lo-
memory location are then available to hold foreground color cation for that block. The color memory locations can hold
information. Such positions are therefore limited to only 8 any of the 16 standard color values.
choices for foreground color instead of the usual 16. Only the When the multicolor screen area is cleared with the
first 8 of the colors listed above are available, since using a BASIC statements GRAPHIC 3,1 or SCNCLR 3, all color
color value greater than 7 would put the position into multi- memory locations are filled with the value from location
color mode. 133/$85, the multicolor source 2 location. The default value
Setting bit 3 of a color location to %1 selects multicolor for that location is 2, but that can be changed with the
mode for that position. In that case, bits 0-2 of the color mem- COLOR statement. The GRAPHIC 4,1 or SCNCLR 4 state-
ory location specify the color of any %11 bit pairs in the char- ments should have the same effect, but they do not. The con-
acter pattern specified for the position. Since only three bits tents of color memory are not affected by either of those
are available, only eight different colors can be selected. The statements. Due to a bug in the SCNCLR routine [$6A79],
first eight of the standard colors (black-yellow) are the only color memory is filled for GRAPHIC modes 2 and 3 rather
ones available, but since bit 3 must be set to %1 for multicolor than 3 and 4. However, the fact that SCNCLR 2 unnecessarily
mode, the value you must store in color memory to get these fills color memory has no obvious effect, since the standard
colors is different from that used for standard character mode. bitmapped mode doesn't use color memory.
You must add 8 to the normal color value. For example, to
make all %11 bit pairs in a character position white, you must Color Banks
store the value 9 (8 + 1, the normal value for white). Com- The 128 actually has two separate IK blocks of RAM available
modore's Programmer's Reference Guide states that the color for this address area—a new feature not available in the Com-
values still produce the standard colors, but this is not correct. modore 64 (or in the 128's Commodore 64 mode). Normally,
For a multicolor mode position, storing a 9 in its color memory the 128 uses one block for character color and the other for
location makes the %11 bit pairs white, not brown. multicolor bitmapped mode. This is why GRAPHIC 4 mode
Since the operating system does not specifically support (split multicolor bitmapped and text) doesn't cause the con-
multicolor character mode, clearing the output window when flicts you might otherwise expect. That is, printing on the text
this mode is active has the same effect it does in standard screen doesn't disturb colors on the multicolor bitmapped
character mode—color memory is filled with the value from screen, and drawing on the multicolor bitmapped screen
the current foreground color location (241/SF1). doesn't disturb the colors on the text screen, even though both
appear to use the same color RAM.
Bitmapped Mode Usage The banking of color RAM is handled by the screen editor
This area of memory is not used by the standard bitmapped portion of the IRQ service routine [$C194j. Bits 0-1 of the
mode (GRAPHIC 1). That mode gets all of its color infor- 8502's on-chip I/O port at location l/$01 determine which
mation from video matrix locations. For multicolor bitmapped block of color RAM is visible in this address area (see the en-
mode (GRAPHIC 3), values stored in this area control the try for location l/$01 in Chapter 2 for details). Block 0 is nor-
color of those dots defined by %11 bit patterns in the bitmap. mally used for the multicolor bitmapped screen and block 1
For the purposes of controlling color, the 160-dot X 200-line for the text screen. If you disable the screen handling portion
462 463
55296-56319 $D800-$DBFF fcnnO0-$DD0F 56576-56591
of the interrupt service routine, you can use this feature for 220 FOR I = 0 T0 3 9 ! P O K E 1024+1,81 sPOKE 1984+1,81 -.NE
other effects. For example, you can maintain two separate XT I
color displays for the text screen, or two separate text screens— 230 FOR 1=0 TO 22:POKE 1064+(1*40),81:POKE 1103+(I
each with its own color memory—or two separate sets of %11 *40),81:NEXT I
pixel color patterns for the multicolor bitmapped screen. 240 REM ** ALTERNATE COLOR RAM BLOCKS
250 POKE 1,PEEK(1) AND 253
Program 8-2 shows one effect you can create with multiple 260 FOR 1=1 TO 65JNEXT I
color memory blocks for a single text screen. Line 110 selects 270 GET A$:IF A$<>"" THEN 310
the BANK 15 configuration (so that the I/O block, including 280 POKE 1,PEEK(1} OR 2
color RAM, will be visible) and stores the value 255 in the 290 FOR 1=1 TO 65:NEXT I
screen mode flag to disable the screen handling portion of the 300 GET A$:IF A$="" THEN 250
interrupt service routine. Remember that split screen modes 310 END
like GRAPHIC 2 and GRAPHIC 4 will not work while this por-
tion of the interrupt service routine is disabled. Lines 130-150
set up block 0 of color RAM, filling the screen borders with an CIA (Complex Interface Adapter) Chip
alternating pattern of black and white positions. Lines 170-190 Registers
perform a similar setup for block 1, but using an alternating 56320-56335/$DC00-$DC0F and
pattern of white and black. Lines 210-230 set up screen mem- 56576-56591/$DD00-$DD0F
ory, drawing a border of ball characters around the screen. The CIA (complex interface adapter) chips perform the major-
Lines 250-310 then switch between the two color blocks, pro- ity of the 128's input and output functions. Between them, the
ducing a marquee effect as the border colors alternate. CIAs are responsible for handling communications with the
keyboard, joysticks, the serial bus (where disk drives and
Program 8-2. Color Bank Switching Demo printers are connected), the RS-232 port (where modems are
connected), and the user port. In fact—with the exception of
100 REM ** COLOR SWITCHING DEMONSTRATION video output provided by the VIC and VDC chips and the au-
110 BANK 15:POKE 216,255:REM DISABLE SCREEN INTERR dio output provided by the SID chip—the list of I/O functions
UPTS performed by devices other than the CIAs is quite short: the
120 REM ** SET UP BLOCK 0 OF COLOR RAM VIC and VDC chips handle light pen input for their respective
130 POKE 1,PEEK(1) AND 254:PRINT"[CLR}" displays, the SID chip reads paddle controllers (although a
140 FOR 1=0 TO 39 STEP 2:POKE 55296+1,0:POKE 55297 CIA reads paddle buttons and selects which pair of paddles is
+I,1:POKE 56256+1,0:POKE 56257+1,1:NEXT I
150 FOR 1=0 TO lliPOKE 55336+(1*80),1:POKE 55375+{
to be read), the processor's on-chip I/O port is used to control
I*S0),0:POKE 55376+(I*80),0:POKE 55415+(1*80),1 some aspects of tape data storage and to read the CAPS LOCK
:NEXT I key, and an MMU register line is used to read the 40/80 DIS-
160 REM ** SET UP BLOCK 1 OF COLOR RAM PLAY key.
170 POKE 1,PEEK(1) OR 1:PRINT"ICLRJ"
180 FOR 1=0 TO 39 STEP 2:POKE 55296+1,1:POKE 55297
All CIA registers are set to zero when the system RESET
+I,0:POKE 56256+1,1:POKE 56257+1,0:NEXT I line is pulled low, as when the reset button is pushed. Most of
190 FOR 1=0 TO 11:POKE 55336+(1*80),0:POKE 55375+( the CIA registers are initialized during the IOINIT routine
I*80),1:POKE 55376+(I*80),l:POKE 55415+(1*80),0 [$E1O9]. Table 8-8 lists the functions of the various CIA regis-
:NEXT I ters. A detailed description of the use of each follows.
200 REM ** SET UP SCREEN MEMORY
210 PRINT"{HOME}[3 DOWNJtRIGHT}tRVSJ PRESS ANY KEY
TO HALT DEMONSTRATION^ SPACES J "
464 465
56320 SDC00 SDC01 56321
Table 8-8. CIA Chip Registers "float" in a high state, and the corresponding data register bit
yn\\ hold a % 1 . Writing to a data register bit for an input line
CIA #1 CIA #2 has no effect on the state of the line, or on the value returned
56320/$DC00 56576/$DD00 Port A data I/O register when the bit is read. However, the value written to the bit will
56321/$DC01 56577/$DD01 Port B data I/O register be retained internally, and will determine the state of the line
56322/$DC02 56578/$DD02 Port A data direction register
56323/$DC03 56579/$DD03 Port B data direction register if the line is changed to an output.
56324/$DC04 56580/$DD04 Timer A latch/counter (low byte) When a port line is set for output, its corresponding data
56325/$DC05 56581/$DD05 Timer A latch/counter (high byte) register bit will control the state of the line. Setting the bit to
56326/$DC06 56582/$DD06 Timer B latch/counter (low byte) %0 will pull the line to a low (0 volts) state, and setting the
56327/$DC07 56583/$DD07 Timer B latch/counter (high byte) bit to %1 will allow the line to go to a high state (+5 volts).
56328/$DC08 56584/$DD08 Time-of-day dock (1/10 seconds) Note that string the bit to %1 doesn't guarantee that the out-
56329/$DC09 56585/$DD09 Time-of-day clock (seconds) put line will be set to a high state. The data CIA can force an
56330/$DC0A 56586/$DD0A Time-of-day dock (minutes) output line low when an external device connected to the line
56331/$DC0B 56587/$DD0B Time-of-day dock (hours) is trying to hold the line high, but it cannot bring an output
56332/$DC0C 56588/$DD0C Serial data register line high when an external device is holding the line low.
56333/$DC0D 56589/$DD0D Interrupt control register Reading the data register bit for an output line returns the cur-
56334/$DC0E 56590/$DD0E Control register A rent state of the line (%0 if the line is low, or %1 if the line is
56335/$DC0F 56591/$DD0F Control register B high). Thus, a line set for output can still be used for a limited
form of input. If the data register bit for the output line is set
CIA #1 Registers to % 1 , then reading that bit will return %1 while the output
This CIA is used to read the keyboard, joysticks, and other de- line is high and %0 when an external device pulls the line
vices connected to the control ports, such as the 128 mouse. It low. This explains how a joystick can be read from port A de-
also selects which pair of paddles will be read. The timers and spite the fact that the lines of that port are normally config-
FLAG input line are used in reading from and writing to tape. ured as outputs.
The chip's serial data communications hardware is used for
fast serial bus I/O. Port B has a feature not available with port A. A special
handshaking output line (from the CIA) designated PC, nor-
56320 SDC00 D1PRA mally high, will go low for one system clock cycle each time
data is read from or written to port B. This can be used to sig-
56321 $DC01 D1PRB nal an external device that data has been written or accepted
I/O port data registers at the port. The PC line from CIA #1 is not connected to any-
The CIA chip has two eight-line data ports, designated A and thing in the 128, but the PC line from CIA #2 is available at
B. Each bit in the data registers is connected to one of the port pin 8 of the user port.
lines (PA0-PA7 for port A and PB0-PB7 for port B). The lines For CIA #1, all port A lines are normally configured as
can be either inputs or outputs, depending on the setting of outputs and all port B lines are normally configured as inputs.
the data direction registers (56322-56323/$DC02-$DC03). For This is to set up the lines for their primary function—reading
port B, bits 6-7 (lines PB6-PB7) can also have special timer the keyboard. Refer to Figure 7-1 and the discussion of the
output functions. See the discussion of the control registers at keyboard-scanning routine [$C55D] in Chapter 7 for more de-
56334-56335/$DC0E-$DC0F for more information. tails on how these lines are used for that purpose.
When a port line is set for input, its corresponding data The second major function of these ports is to read the
register bit will reflect the state of the line. The bit will hold status of digital controllers connected to the two control ports
%0 when the line is pulled low (0 volts), or %1 when the line °n the side of the 128. Each control port is connected to five
is high ( + 5 volts). An unconnected input line, or one con- lines of one of the CIA #1 ports. Port B is connected to control
nected to a device that isn't actively pulling the line low, will
466 467
56321 $DC01 $DC01. 56321
port 1 {the front one) and port A to control port 2 (the back ortl Control port 2 Joystick
one), which is the opposite of what you might expect. The SDC01) CIA port A. ($DC00) direction
connections are as follows: $11111111 255/SFF %oiinm 127/$7P not pressed
fciiiiino 254/SFE %01111110 126/S7E up
CIA port bit Controller port pin Joystick function %11111101 253/$FD %01111101 125/$7D down
0 1 ftllUlOll 251/SFB %01111011 123/$7B left
up £11111010 250/$FA %01111010 122/S7A up + left
1 2 down £11111001 249/$F9 %01111001 121/579 down + left
2 3 left %iinom 247/$F7 %omom 119/$77 right
3 4 #11110110 246/$F6 %01110110 118/$76 up + right
right
4 6 %11110101 245/$F5 %onioioi 117/$75 up + left
button
If the fire button is pressed, bit 4 of the data register will also
The control port pins are usually described in terms of be set to %0, and the values listed above will be reduced by
their joystick functions, since the joystick is the device most
commonly connected to the ports. A joystick is a very simple 16/$10.
device consisting of five switches, one for each of the four pri- If you'd prefer to read %1 bits instead, try the following
mary directions and one for the fire button. The switches are code:
normally open, meaning that no connection is made when the Control port 1 Control port 2
joystick is not being pressed. Remember that unconnected CIA LDA $DC01 LDA $DC00
port lines float to a high state ( + 5 volts), so the corresponding AND#$1F AND #$1F
EOR #$1F EOR #$1F
CIA port bits will be % 1 . Pressing the stick in one of the eight
possible directions (four primary directions and four diagonals) Using this method, the accumulator will hold one of the fol-
closes one or two of the switches, grounding the CIA port lowing values after the port is read:
lines and forcing the corresponding bit or bits to %0. Pressing
the fire button grounds that line, so it is possible to have as Value Joystick direction
many as three lines simultaneously grounded. 0/$00 not pressed
l/$01 up
For reading the joysticks, BASIC provides the JOY func- 2/$02 down
tion [$8203], which returns a value from 1-7, depending on 4/$04 left
the direction the stick is pressed (the value is 0 if it is not be- 5/$05 up + left
ing pressed), with 128 added if the fire button is pressed. To 6/$06 down + left
read the joystick from machine language, you simply read the 8/$08 right
corresponding CIA port data register and check for %0 bits. 9/$09 up + right
Even though the port A lines are normally set up as outputs, 10/$00 down + right
you can still read the joystick without switching the lines to Pressing the fire button will add 16/$10 to any of the values
inputs. The keyboard scan routine leaves all port A bits except listed above.
bit 7 set to % 1 , so it is still possible for external devices like You should be aware, however, that using control port 1
the joystick to pull the lines low (bit 7 of that port will nor- (CIA port B) for joystick input can have an undesirable side ef-
mally always be %0). The possible port readings are as follows: fect. Since the input lines of that port are also used for reading
the keyboard, the keyscan routine [$C55D] has no way to tell
whether the port lines are being grounded by keypresses or
468 469
56321 $DC01 SDCO3 56323
470 471
56324 $DC04
6PC07 56327
timer A underflows. This effectively ties the two timers to- 56329/$DC09: Bits 0-3 hold the ones digit for seconds. Bits
gether to form a 32-bit countdown value, allowing countdown 4_6 of this register hold the tens digit (only three bits are
intervals of up to 70 minutes. The operation of timer B is con- needed, since this digit will never be greater than %101 =
trolled by the register at 56335/$DC0F. 5 the seconds count rolls over to $00 after reaching $59.) Bit
For CIA #1, the IOINIT routine [$E109], part of both the 7 is unused. Writing to that bit has no effect, and it always re-
reset and RUN/STOP-RESTORE sequences, loads the latch turns a %0 when read.
for this timer with 65535/$FFFF and starts the timer running
in continuous mode. There is no obvious reason for this step. 56330/$DC0A: Bits 0-3 hold the ones digit for minutes. Bits
The only use of timer B by 128 ROM routines is during tape 4-6 hold the tens digit. Bit 7 is unused. Writing to that bit has
I/O, where it is used to generate IRQ interrupts to drive the no effect, and it always returns a %0 when read.
reading and writing of data. Upon completion of a tape opera- 56331/$DC0B: Bits 0-3 of this register hold the ones digit for
tion, the timer will be left halted and set for one-shot mode. hours. Bit 4 holds the tens digit for hours (only one bit is
needed, since this digit will always be either 0 or 1). Bits 5-6
56328 SDC08 D1TOD1 are unused. Writing to these bits has no effect, and they al-
56329 $DC09 D1TODS ways return %0 when read. Bit 7 is the AM/PM flag. The 12-
56330 $DC0A D1TODM hour format time value is taken to represent AM (midnight-
56331 $DC0B D1TODH noon) when this bit is %0 and PM (noon-midnight) when the
Time-of-day clock registers bit is % 1 . Be sure to remember this bit when setting an alarm
The time-of-day (TOD) clock is a special feature of the CIA. It time.
keeps time in hours, minutes, seconds, and tenths of sec- The order in which you read and write these registers is
onds—units more useful to humans than the jiffies of the sys- important. When reading the clock, the registers latch (remain
tem software clock or the fractional microseconds of timer A constant) after you read the hours register until you read from
or B. There are actually two sets of registers at these locations, the 1/10-seconds register. The clock continues to count inter-
the time and the alarm. By storing an alarm value here, you nally; only the register values remain constant. Thus, each
can trigger an internal interrupt (and, optionally, an external read of the hours register must be followed by a read of the
IRQ request) when a specified time is reached. When you read 1/10-seconds register, even if you don't care about the 1/10-
the registers, you always see the time value (the alarm setting second value. Likewise, the clock stops whenever a value is
is never visible). When you're writing to the register, bit 7 of written to the hours register, and does not start again until a
control register B (56335/SDCOF) determines whether the value is written to the 1/10-seconds register. Thus, for both
value being written will set the time or the alarm. reading and writing you should start with the hours register
and end with the 1/10-seconds register.
The time is kept in 12-hour format, with bit 7 of the
hours register used as a flag to indicate AM or PM. The time The following routine illustrates the use of the time-of-
data in the registers is in binary coded decimal (BCD) format. day clock by displaying the current time in the upper left cor-
In this format, each half-byte (nybble) contains a value which ner of the screen:
represents one decimal digit. For example, if the minutes regis- D00 LDA #$89 ;Load clock registers with desired
ter contains the value %00100110, equivalent to 38/$26, the D02 STA $DC0B ; initial time. (This example uses
minutes digits should be interpreted as 2 and 6—26 minutes D05 LDA #$05 ; 9:05:00.0 PM)
past the hour, rather than 38 minutes. The register bits should D07 STA $DC0A
be interpreted as follows: D0A LDA #$00
DOC STA $DC09
56328/$DC08: Bits 0-3 hold the 1/10-seconds digit. Bits 4-7 DflF
i LDA #$00
are unused. Writing to those bits has no effect, and they al-
ways return %0 when read.
474
475
56331 56332
$DCOB $DCOC
Dll STA $DC08 ;Gock starts when this register is written routine. Thus, both are free for your own programming. All
D14 LDA $DC0B ;Read hours byte (this latches the time value)
D17 BMI $OD1D clock registers are reset to %0 when the system is reset.
;Add either an A or a P to the time string,
D19 LDX #$41 ; depending on the state of the AM/PM bit
DIB BNE $0DlF 56332 8DC0C D1SDR
DID LDX #$50 Serial data register
D1F STX $0D70 The CIA supports serial (bit-by-bit) data transfers in hardware.
D22 AND #$7F ,Mask off the AM/PM bit This register holds the byte of data to be sent over the CIA's
D24 JSR $0D54 ;Convert the hours byte to two characters SP (serial port) line, or the byte read from the line. At any
D27 CMP #$30 ;RepIace leading zero with a space given time, the CIA serial line must be configured for either
D29 BNE $0D2D input or output. This is controlled by the setting of bit 6 of
D2B LDA #$20
D2D
control register A (56334/$DC0E).
STA $0D67 ;Add hours-digit characters to string
D30 STX S0D6S When the line is set for input, the state of the SP line is
D33 LDA $DC0A ;Read minutes byte read as a data bit each time there is a low-to-high (0 to +5
D36 JSR $0D54 ;Convert to two characters volts) transition on the CNT input line. (CNT must be driven
D39 STA $0D6A ;Add minutes-digit characters to string by the external device which is sending data.) As each bit is
D3C STX $0D6B read, it is transferred into an internal serial shift register.
D3F LDA $DC09 ;Read seconds byte When an entire byte has been read (after eight pulses of the
D42 JSR $0D54 ;Convert to two characters CNT line), the value in the internal shift register is transferred
D45 STA $0D6D ;Add seconds-digit characters to string to this register and an interrupt will be indicated in bit 3 of the
D48 STX $0D6E CIA interrupt register (56333/$DC0D). At this point, the re-
D4B LDA $DCO8 ;Read 1/10-seconds byte (to unlatch time) ceived byte can be read from the register.
D4E JSR $0D62 ;Print time string
D51
When the line is set to be an output, data written to this
JMP $0D14 ;Repeat indefinitely register will be transferred into the internal shift register and
;Convert BCD byte to two ASCII characters then sent out a bit at a time over the SP line. Timer A deter-
TJ S4 PHA ;Stash the byte mines the rate at which bits will be sent. The transmission will
D55 AND #$0F ;Mask off all but the lower four bits begin immediately if timer A is running; otherwise, it begins
D57 ORA #$30 ;Add base ASCII numeral value
D59 TAX
when the timer is started. Bits will be written on the serial line
;Leave low digit in X register at one-half the countdown rate of timer A. That is, timer A
D5A PLA ;Retrieve original value
D5B LSR must underflow twice for each bit sent. This clock signal ap-
;Move high four bits into low nybble pears as output on the CNT line. After all eight bits are sent,
D5C LSR
D5D LSR an interrupt will be indicated in bit 3 of the CIA interrupt reg-
D5E LSR ister (56333/$DC0D) to indicate that another byte can be sent.
D5F ORA #$30 ;Add base ASCII numeral value This hardware serial data communications feature went
D61 RTS unused in the Commodore 64, but in the 128 it is used to sup-
D62 JSR $FF7D ;Print time string using Kernal PRIMM port the fast serial bus. The only fast serial peripheral device
> D 6 5 13 12 30 30 3A 30 30 3A ;String characters: currently in widespread distribution is the 1571 disk drive, but
>D6D 30 30 20 41 4D 20 00 ; {HOME}{RVS}00:00:00 AM others may appear in the future. For CIA #1, the SP line is
D74 RTS
connected to the serial bus DATA line (with additional cir-
Neither CIA's time-of-day clock is used by 128 mode, al- cuitry to prevent conflicts with slow serial communications)
though CP/M does make use of the CIA #1 dock for time- and the CNT line is connected to the SRQIN line. The CIA #1
keeping. None of these registers is initialized by any 128 ROM SP and CNT lines are also available from the user port, at pins
5 and 4, respectively.
476 477
56333 $DCOD 56333
SDCOD
56333 SDCOD D1ICR Bit 7 controls the interrupt mask register function. When
Interrupt control register vou're writing to this register, bit 7 determines which mask
The CIA chip has five internal interrupt sources: timer A bits will be set or cleared. If bit 7 is set to %1 in a value writ-
underflow, timer B underflow, time-of-day clock alarm, serial ten to this register and any of bits 0-4 in the value are also set
data buffer full or empty, and FLAG signal. The CIA can also to %1/ then the corresponding interrupt mask bits will be set
generate an interrupt request output signal as a result of any and the specified interrupt or interrupts will generate an exter-
of these conditions. The location actually has two different nal interrupt request output. The mask bits correspond to the
functions, depending on whether it is being read from or writ- sources listed above the data register. For example, to enable
ten to. When you read from this register, you see the contents timer B as an interrupt source you would write a value to the
of an internal interrupt data register that indicates which inter- register which has bits 1 and 7 set to % 1 — LDA #$82:STA
rupts, if any, have occurred. When you write to this register, $DC0D. (Bits in the value which are %0 are not significant.) If
the value goes to an internal interrupt mask register that speci- bit 7 in the value written to the register is set to %0 and any
fies which interrupts—if any—are to result in an external in- of bits 0-4 in the value are % 1 , then the corresponding mask
terrupt request being generated. The data register is read-only bits will be cleared and the specified interrupt or interrupts
{it can't be written to), and the mask register is write-only (it will be disabled. For example, you could use LDA #$0F:STA
can't be read from). $DC0D to clear all except FLAG interrupts. (Again, bits in the
When you're reading from the register, bits 0-4 indicate value which are %0 have no effect.)
which interrupts have occurred since the last time those bits When external interrupt requests are enabled, you can
were read. The bit is set to %1 when the corresponding inter- read bit 7 to determine whether any interrupts have occurred.
rupt occurs, regardless of whether or not the source is set to When read, bit 7 will be %0 if no CIA source has generated
trigger an external interrupt request output. All these bits are an interrupt request, or %1 if an interrupt request output has
automatically cleared to %0 after the register has been read. been generated as the result of one or more enabled internal
The interrupt type indicated by the individual bits is as follows: CIA interrupt conditions. Remember, however, that all the
Bit Interrupt source data bits in this register are cleared to %0 after the register is
0 Timer A underflow read. Thus, you must preserve the read register value if you
1 Timer B underflow wish to determine which source produced the interrupt re-
2 Time-of-day clock alarm quest. For example, you shouldn't test bit 7 with the machine
3 Serial data buffer full or empty language BIT instruction, since that will result in the loss of
4 High-to-low transition on FLAG input line the data register bit settings.
A timer underflow occurs when the timer counts down below For CIA #1, the interrupt request output is connected to
zero. A time-of-day clock alarm occurs when the time in the the processor's IRQ input line, so interrupt requests from CIA
clock registers matches the value in the alarm registers. The #1 result in IRQ interrupts to the processor. The IOINIT rou-
serial-buffer-empty condition occurs during output after all tine [SE109] clears all interrupt mask bits, so initially no inter-
eight bits for a byte have been written on the serial port (SP) rupts are enabled. Some operations enable interrupts for the
line, and a buffer-full condition occurs during input after eight duration of their activity. Tape I/O, which is interrupt-driven,
bits have been read from the SP line. The FLAG line is a spe- uses timer A, timer B, and FLAG interrupts as IRQ sources.
cial input provided on the CIA specifically for the purpose of Fast serial bus I/O uses internal serial data buffer interrupts,
generating interrupts. A FLAG interrupt occurs whenever the but does not trigger external IRQ requests. See the tape and
device connected to the FLAG line causes a high-to-low volt- fast serial routines in Chapter 9 for details. You are, of course,
age transition ( + 5 to 0 volts) on the line. ' r ee to set up your own CIA #1 interrupts, but you must write
your own interrupt service routine. The standard IRQ handler
Bits 5-6 are unused. Writing to them has no effect, and [5>FA65] merely reads this register to clear it, and ignores the
they always return %0 when read.
1
478
479
56334 $DCOE flpCOE 56334
value read. See Appendix A for more information on inter- tvveen high and low states. The output mode is controlled by
rupts. In Commodore 64 mode (and in the original Commo- bit
t
2 of this register. Writing a %0 here disables timer A out-
dore 64), timer A interrupts from CIA #1 were the source for put and restores PB6 to the state and function defined in the
the system's 1/60-second jiffy IRQ. However, 128 mode in- port B data and data direction registers.
stead uses raster interrupts from the VIC chip for that function. For CIA # 1 , this bit is set to %0 during the IOINIT rou-
tine [$E109], and is not changed by any 128 ROM routine.
56334 $DCOE D1CRA The PB6 output feature is not useful on CIA # 1 , since the PB6
Control register A line for that CIA is connected only to a keyboard row scan-
This register controls the operation of timer A, except for bits ning line, and is not available externally. However, the PB6
6-7, which control serial data port and time-of-day clock func- line from CIA #2 is available at pin K of the user port, so this
tions, respectively. See the entry at 56324-56325/$DC04-$DC05 feature could be used with timer A of that CIA.
for more information on timer A. Bit 2: When bit 1 of this register is set to allow timer A to gen-
Bit 0: This bit acts as the ignition switch for timer A. Writing a erate output on the PB6 line of port A, this bit controls the
%0 here stops the timer. If the timer is currently stopped, type of output. (This bit has no effect when bit 1 is %0.) The
writing a %1 here causes the counter to begin decrementing two selections for output type are pulse and toggle. For pulse
its current contents (unless the force load strobe, bit 4 of this output, selected when this bit is set to %0, the output line is
register, is also set to %1—in that case, the latch value is held low except for a very brief high pulse each time timer A
loaded into the counter before counting resumes). Writing a overflows. The line will be held high for one cycle of the O2
%1 here when the bit is already set to %1 has no effect. Set- clock rate. For the 128, that is equal to 0.978 microseconds in
ting the bit to %0 when it has previously been %1 halts the NTSC (North American) systems, or 1.01 microseconds on
timer, leaving the counter holding the value it has reached PAL (European) systems. For toggle output, selected when this
when stopped. When the timer is set for one-shot mode, this bit is set to % 1 , the PB6 line switches state—low-to-high or
bit will automatically be reset to %0 when the count under- high-to-low—each time the timer underflows, starting from a
flows. In this case, the counter will be reloaded with the latch high state.
value. For CIA # 1 , this bit is set to %0 during the IOINIT rou-
For CIA #1, the IOINIT routine sets this bit to %0, so tine [$E109], and is not changed by any 128 ROM routine.
timer A is initially stopped. The ROM routines for tape I/O
use this timer to generate IRQ interrupts for reading and writ- Bit 3: This bit controls whether timer A runs in continuous or
ing tape bits, but the bit is reset to %0 upon completion of one-shot mode. In continuous mode, selected when this bit is
any tape operation. The Kernal SPOUT routine [$E5D6], set to %0, the timer will perform repeated countdowns. After
which prepares the fast serial bus for output, starts the timer each underflow, the counter is reloaded with the latch value
and leaves it counting. (Timer A determines the rate at which and restarted. In one-shot mode, selected when this bit is set
data is sent over the fast serial lines.) The Kernal fast serial t° % 1 , the timer counts down to underflow only once, at
output routines end with calls to the SPIN routine [$E5C3], which time bit 0 of this register is reset to %0 to halt further
which resets this bit to %0, halting the timer. counting. However, the latch value is still transferred to the
counter when the underflow occurs.
Bit 1: This bit controls whether or not timer A generates out- For CIA # 1 , the IOINIT routine [$E109] initializes this bit
put on the PB6 line of port B. Writing a %1 here enables PB6 to % 1 , Tape I/O routines use this timer, but also in one-shot
output. When PB6 is selected for timer A output, the line wode, so the bit should still be set to %1 after any tape opera-
automatically becomes an output, regardless of the setting of tion is performed. The Kernal fast serial output routines will
the data direction register bit for that line. The output on PB6 change this bit to %0 to run the timer in continuous mode.
will be either short pulses or a regular toggling of the line be- However, upon completion of any fast serial output operation,
480 481
56334 $DCOE 56335
$DCOF
the port is reset for fast serial input, which includes resetting
this bit to %1 for one-shot mode. timer A. See the discussion of the serial data register for more
information.
Bit 4: Writing a %1 to this bit, called the force load strobe, For CIA #1, this bit is initialized during the IOINIT rou-
causes the contents of the timer A latch to be transferred to tine to %0. The 128 uses the CIA #1 serial data register for
the counter, regardless of whether the timer is currently run- fast serial bus communications, so the bit must be set to %1
ning or stopped. Using the strobe bit while the timer is run- whenever fast serial output is being performed. However, after
ning allows you to modify the counter contents in the middle the output has been completed the Kernal fast serial output
of a countdown. Writing a %0 to this bit has no effect. This bit routines reset the bus for input, which includes resetting this
is write-only; it always returns a %0 when read. bit to %0.
Bit 5: This bit controls which of two possible events will drive Bit 7: This bit controls a time-of-day clock function rather than
timer A. Two different input signals can be used to make the a timer A function. It determines the rate at which the time-of-
timer decrement. The timer will be decremented once for each day clock will be incremented. The clock is driven by the
cycle of the specified event, but only if bit 0 of this register is CIA's TOD input pin, which, in the 128, is connected to cir-
set to %1 to allow counting. When this bit is set to %0, the cuitry which produces a clock signal from the AC power sup-
timer will be driven by the system O2 clock, which provides ply. This signal will have the same frequency as the local
a "tick" every 0.978 microseconds in NTSC (North American) power supply, generally 60 hertz (60 cycles per second) in
systems, or 1.01 microseconds on PAL (European) systems. North America and 50 hertz in Europe. Setting this bit to %0
The maximum delay between underflows with this clock rate specifies that the 1/10-seconds digit of the clock time should
is in the neighborhood of 1/15 second. Setting the bit to %1 be incremented once for every 6 cycles of the TOD signal (for
makes the CIA's CNT line the clock source, so that an external a 60-hertz source), while setting it to %1 specifies that the
source can drive the count rate. In this case, the counter will digit should be incremented on every fifth cycle (for a 50-hertz
be decremented once each time the external device connected source). Specifying an incorrect rate will make the time-of-day
to CNT provides a low-to-high transition on the line. For CIA clocks in your system count either too fast or too slow.
#1, the CNT line is available at pin 4 of the user port. The For CIA #1, this bit is initialized to %0 during the IOINIT
CNT line is also used as the clock source for the fast serial routine [$E109], and that setting is not changed by any other
bus, and is connected to the SRQIN line of the serial port. 128 ROM routine. This is the proper setting for North Amer-
However, the line from SRQIN will be an input only when ica, but unless there is a different version of the ROM in Euro-
the FSDIR bit (bit 3) of the MMU mode configuration register pean 128s, overseas users will need to change this bit to get
at 54533/$D505 is set to %0. proper timekeeping.
For CIA #1, this bit is initialized to %0 during the IOINIT
routine [$E109], and that setting is not changed by any other 56335 $DC0F D1CRB
128 ROM routine. Timer A must be set to count system clock Control register B
pulses in order for tape operations to perform properly. This register controls the operation of timer B, except for bit 7,
Bit 6: This bit does not control a timer A function, but instead which controls a time-of-day clock function. See the entry at
specifies the direction of data flow on the CIA's serial port 56324-56325/$DC04-$DC05 for more information on timer B.
(SP) line. When this bit is set to %0, the SP line is an input. Bit 0: This bit acts as the ignition switch for timer B. While the
Data read on the line will be collected in the serial shift regis- bit is %0, the timer is stopped. If the timer is currently
ter until a full byte has been received; then an interrupt will stopped, writing a %1 here starts the counter. The countdown
be generated. When this bit is set to % 1 , the SP line is an out- will resume with the current counter contents unless bit 4 of
put, and data written to the serial data register at 56332/ this register is also set to %1 to force the latch value to be re-
$DC0C will be sent out on the SP line at a rate depending on loaded. Writing a %1 here when the bit is already set to %1
482
483
^
56335 $DCOF
$PCOF_ 56335
has no effect. Setting the bit to %0 when it has previously For CIA # 1 , this bit is set to %0 during the IOINIT rou-
been %1 halts the timer, leaving the counter holding whatever tine [$E109], and is not changed by any 128 ROM routine.
count value it has reached when stopped. When the timer is
set for one-shot mode, this bit is automatically reset to %0 Bit 3: This bit controls whether timer B runs in continuous or
when the count underflows. In this case, the counter is re- o ne-shot mode. In continuous mode, selected when this bit is
loaded with the latch value. set to %0, the timer will perform repeated countdowns. After
each underflow, the counter is reloaded with the latch value
For CIA #1, the IOINIT routine sets this bit to % 1 , so and restarted. In one-shot mode, selected when this bit is set
timer B is normally running (although there is no obvious rea- to %1/ the timer counts down to underflow only once, at
son for this). The timer is used in one-shot mode for tape I/O,
so this bit will be set to %0 (and the timer will be stopped) which time bit 0 of this register is reset to %0 to halt further
upon completion of any tape operation. counting. However, the latch value is still transferred to the
counter when the underflow occurs.
Bit 1: This bit controls whether or not timer B generates out- For CIA #1, the IOINIT routine [$E109] initializes this bit
put on the PB7 line of port B. Writing a %1 here enables PB7 to %0, so timer B starts running continuously. However, the tape
output. When PB7 is selected for timer B output, the line auto- I/O routines use this timer in one-shot mode, and this bit will
matically becomes an output, regardless of the setting of the be left set to %1 after any tape operation has been performed.
data direction register bit for that line. The output on PB7 will
be either short pulses or a regular toggling of the line between Bit 4: Writing a %1 to this bit, called the force load strobe,
high and low states. The output mode is controlled by bit 2 of causes the contents of the timer B latch to be transferred to the
this register. Writing a %0 here disables timer B output and re- counter, regardless of whether the timer is currently running
stores PB7 to the state and function defined in the port B data or stopped. Using the strobe bit while the timer is running al-
and data direction registers. lows you to modify the counter contents in the middle of a
For CIA #1, this bit is set to %0 during the IOINIT rou- countdown. Writing a %0 to this bit has no effect. This bit is
tine [$E109], and is not changed by any 128 ROM routine. write-only; it always returns a %0 when read.
The PB7 output feature is not useful on CIA #1, since the PB7 Bits 5-6: These bits control which of four possible events will
line for that CIA is connected only to a keyboard row scan- drive timer B. That is, four different input signals can be used
ning line, and is not available externally. However, the PB7 to make the timer decrement. The timer will be decremented
line from CIA #2 is available at pin L of the user port, so this once for each specified event, but only if bit 0 of this register
feature could be used with timer B of that CIA. is set to %1 to allow counting. The four possible selections are
Bit 2: When bit 1 of this register is set to allow timer B to gen- as follows:
erate output on the PB7 line of port B, this bit controls the Bits
type of output. (This bit has no effect when bit 1 is %0.) The 6 5 Timer B driving source
two selections for output type are pulse and toggle. For pulse 0 0 System <&2 clock
output, selected when this bit is set to %0, the output line is 0 1 CNT line transitions
held low except for a very brief high pulse each time timer B 11 0 Timer A underflows
overflows. The line will be held high for one cycle of the O2 1 Timer A underflows while the CNT line is high
clock rate. For the 128, that is equal to 0.978 microseconds in The default source, the system O2 clock, provides a "tick"
NTSC (North American) systems, or 1.01 microseconds on every 0.978 microseconds in NTSC (North American) systems,
PAL (European) systems. For toggle output, selected when this °r 1.01 microseconds on PAL (European) systems. The maxi-
bit is set to % 1 , the PB7 line switches state—low-to-high or mum delay between underflows with this clock rate is in the
high-to-low—each time the timer underflows, starting from a neighborhood of 1/15 second. The CNT option (%01) allows
high state. a
n external source to drive the count rate. In this case, the
484 :
485
56336-56575 $DC10-$DCFF 56577
SDDOI
488 489
56578 $DD02 SDDOD 56589
490
491
56590 $DD0E 6nF00-$DFFF 57088-57343
492
493
57088-57098 $DF00-$DF0A jDFOO 57088
REC (RAM Expansion Controller) Chip actually shuts down the 8502 microprocessor and takes com-
Registers plete control of the system. Because the REC is optimized for
the task of transferring data, it can perform its transfers with
57088-57098/$DF00-$DF0A blinding speed. The specifications for the 1700 and 1750 mod-
The REC chip is different from the other chips described in ules claim transfer rates of 1 million bytes per second for
this chapter in that it isn't part of the 128's internal hardware. stash, fetch, or verify operations, and half that rate for swap
No REC chip will be present unless you have a model 1700 or operations. In more practical terms, the REC can completely
1750 RAM Expansion Module plugged into the memory ex- fill the 8502's 64K address space in about 1/16 second, or
pansion port, since the REC is part of the hardware in the load an 8K bitmapped screen in 1/128 second—faster than
module. However, with an expansion module installed, the the 8502 itself can move the equivalent amount of data.
registers for the REC appear here just like the other hardware Table 8-9 lists the REC registers. A detailed description of
chip registers. Other chips could be addressed in this I/O slot, each register follows.
but the Kernal DMA_CALL routine [$F7A5] and the BASIC
STASH, FETCH, and SWAP statements all attempt to store
values in the REC registers listed below. Table 8-9. REC Chip Registers
Some would claim the expansion modules increase the Address Register
amount of available RAM in the system. This claim is a bit 57088/$DFO0 Status register
misleading. The 8502 processor cannot directly access any of 57089/$DF01 Command register
the 128K of RAM in a model 1700 expansion module or any 57090/$DF02 System RAM base address (low byte)
of the 512K in a 1750. RAM from the modules never appears 57091/$DF03 System RAM base address {high byte)
in the 128's normal address space; it cannot be used to fill in 57092/$DF04 Expansion RAM base address (low byte}
the missing RAM blocks 2 and 3 in the memory banking 57093/$DF05 Expansion RAM base address (high byte)
specifications. The REC chip is the 128's only gateway to the 57094/$DF06 Expansion RAM bank
expansion module RAM. The REC is actually a highly special- 57095/$DF07 Count of bytes to transfer (low byte)
ized processor dedicated to the task of transferring the con- 57096/$DF08 Count of bytes to transfer (high byte)
57097/SDF09 Interrupt mask register
tents of blocks of memory. It can perform four bask operations: 57098/$DF0A Address control register
transferring data from system RAM to expansion RAM (called
a stash operation), transferring data from expansion RAM to
system RAM (called a fetch operation), exchanging the con- 57088 SDFOO DMA ST
tents of an area of system RAM and an area of expansion Status register
RAM (called a swap operation), and comparing the contents of This register is read-only, meaning that writing values to this
an area of system RAM and an area of expansion RAM (called location has no effect on the setting of any register bits.
a verify operation). Bits 0-3: These bits hold a constant number (similar to a ROM
You'll notice that these are essentially the same basic location) indicating the version of the REC chip installed in
functions performed by a disk drive, which is why the expan- the expansion module. In the initial release of expansion mod-
sion module is sometimes referred to as a RAMdisk. The latest ules the value here is 0 (%0000), but this may change as re-
version of CP/M supports the expansion module as a virtual vised versions of the REC are introduced.
disk drive, referenced as drive M:. The 128-mode operating Sit 4: This bit indicates the amount of RAM available in the
system doesn't have this feature built-in, but a program to expansion module. A %0 here indicates that the REC is in a
provide a 128-mode RAMdisk would not be impossible to write. mode] 1700 module with 128K of RAM, while a %1 here indi-
The REC is a DMA (direct memory access) device, mean- cates that the REC is part of a model 1750 module with 512K
ing that when called upon to perform a transfer operation it of RAM.
494 495
57089 SDF01 57089
6PF0L
Bit 5: This bit, the fault flag, is set to %1 when a mismatch is eration and the Y register containing the REC command (the
detected during a verify operation. The bit is set whenever a value to be stored in this register). For example, BASIC sup-
verify error occurs, regardless of whether or not the cor- ports stash, fetch, and swap operations, but not verify. The fol-
responding bit in the interrupt mask register (57097/$DF09) is lowing routine is an example of how the current BASIC
set to trigger an interrupt on this condition. The bit is cleared program text could be verified against the expansion RAM
to %0 whenever the register is read. contents:
Bit 6: This bit, the end-of-block flag, is set to %1 when all
bytes for the operation have been transferred or verified. The 499 REM * SET SYSTEM STARTING ADDRESS TO START-OF-
PROGRAM VALUE
bit is set whenever an operation is successfully completed, re- 500 BANK 15:POKE 57090,PEEK(45):POKE 57091,PEEK{46
gardless of whether or not the corresponding bit in the inter- )
rupt mask register (57097/$DF09) is set to trigger an interrupt 509 REM * SET NUMBER OF BYTES TO END-OF-PROGRAM MI
on this condition. The bit is cleared to %0 whenever the regis- NUS START-OF-PROGRAM
ter is read. 510 POKE 57095,PEEK(4624)-PEEK{45):POKE 57096,PEEK
(4625)-PEEK(46)
Bit 7: This bit, the interrupt pending flag, signals that the REC 519 REM * SET EXPANSION ADDRESS AND BANK
has generated an IRQ interrupt. The REC can generate an IRQ 520 POKE 57092,0:POKE 57093,0:POKE 5 7 0 9 4 , 0
in response to two conditions: a verify error (fault) and the 529 REM * USE KERNAL DMA CALL ROUTINE {BANK = $00,
normal completion of an operation (end-of-block). Since the COMMAND = $83)
530 SYS 6 5 3 6 0 , , 0 , 1 3 1
8502 processor is inactive while the REC is performing a 539 REM * CHECK STATUS REGISTER FOR VERIFY ERROR F
transfer, the IRQ is actually generated after the REC returns LAG
control to the 8502, No IRQ will be generated unless the inter- 540 IF (PEEK(57088) AND 32 ) = 0 THEN PRINT"VEHIFY OK
rupt enable bit in the register at 57097/$DF09 is set to %1 ":ELSE PRINT"BYTE MISMATCH AT ADDRESS";PEEK(45)
+256*PEEK(46)+PEEK(57095)+256*PEEK(57096)-l
and one or both of the interrupt condition bits in that register
are set. Of course, a verify error will occur if a copy of the program
The normal IRQ interrupt handling routine [$FA65] has not been previously stashed in the corresponding area of
doesn't consider the REC as a source of interrupts, so you will expansion memory.
have to write your own routine to process IRQs from the REC.
See Appendix A for more information on interrupt handling. Bits 0-1: These bits determine the type of operation to be per-
Bits 5-7 of this register are cleared to %0 whenever the regis- formed by the REC. The four possible operations are specified
ter is read, so when testing this bit to determine whether an as follows:
interrupt has occurred you must save the value read from the Bits
register if you wish to subsequently test bits 5 and 6 to deter- 1 0 Operation
mine which event has caused the interrupt. 0 0 Stash (transfer from system memory to expansion RAM)
0 1 Fetch (transfer from expansion RAM to system memory)
57089 SDF01 1 0 Swap (exchange contents of system memory and expansion
DMA CMD RAM)
Command register
1 1 Verify (compare contents of system memory and expansion
This register determines the type of operation to be performed RAM)
by the REC. While it is possible to write directly to this regis- These bits are set to %00 during system reset. They retain
ter, the preferred practice is to use the Kernal DMA_CALL their settings after an operation is completed.
routine [$FF50], To use DMA_CALL, first set all the other
REC registers to their desired values; then call the routine with pits 2-3: These bits are described in Commodore literature as
the X register containing the system bank number for the op- "reserved," meaning that they have no function in the present
version of the REC, but may in some future version. For now,
496 497
57089 $DF01 $DF03. 57091
the bits seem merely to hold whatever value is written to 57090 $DF02 DMA ADL
them. They are set to %00 during system reset. 57091 $DF03 DMA ADH
Bit 4: This bit, called the $FF00 flag, controls the execution System memory base address registers
mode for REC operations. When this bit is %0, operations do This register pair specifies the starting address in the 128's ad-
not begin immediately when bit 7 of this register is set to % 1 , dress space for the current REC operation. The first register
but rather are deferred until a write to the MMU mode con- (57090/$DF02) holds the low byte and the second (57091/
figuration register (65280/$FF00) occurs. This is convenient $DF03) holds the high byte. The memory configuration in which
because it allows the memory configuration to be changed this address is seen is determined by the values in the MMU
after the MMU registers are set up. When this bit is % 1 , the configuration register (65280/$FF00) and RAM configuration
operation specified in bits 0-1 begins immediately when bit 7 register (54534/$D506). The configuration register setting de-
is set. This bit is set to %1 during reset, and also whenever an termines which ROM, if any, will be seen in the configuration,
operation is completed. Thus, the bit must always be specifi- and whether or not the I/O block will be visible. However, for
cally written with a %0 to enable the deferred execution option. REC data transfers the configuration register determines only
Bit 5: This bit, called the load flag, controls a special feature whether or not RAM is visible—not the block from which the
known as autoload mode. During a REC operation the system RAM is seen. That is, the setting of configuration register bits
and expansion base registers and expansion bank register are 6-7 is irrelevant to the REC. For DMA operations like REC
incremented and the byte-count registers are decremented. transfers, the RAM block is instead determined by the setting
When this bit is %0 {the default state after a reset), the regis- of bits 6-7 of the RAM configuration register. If you want to
ters are left at the end of an operation containing the final ad- transfer data to or from block 1 of RAM, you'll need to set bit
dresses and byte count. However, setting this bit to %1 6 of location 54534/SD506 to % 1 .
enables the autoload feature, in which case the address, bank, That RAM configuration register bit also controls the
and byte-count registers are automatically reloaded with their block from which the VIC chip (another DMA device) gets its
starting values after the operation is completed. This can be screen and character information, so be sure to reset the MMU
handy if you are repeatedly performing an operation involving register to its original value immediately after the REC opera-
the same area of memory. tion is completed. Switching the VIC to a bank with no pre-
pared screen data will turn the 40-column display to garbage,
Bit 6: This bit is described in Commodore literature as "re- but in practice REC operations are completed so quickly that
served," meaning that it has no function in the present version as long as the RAM configuration register bit is restored imme-
of the REC, but may in some future version. For now, the bit diately after the REC operation is completed, the result of the
seems merely to hold whatever value is written to it. switching is merely a barely noticeable flash of the screen. Of
Bit 7: This bit, known as the execute flag, is used to signal the course, the VIC block switching has no visible effect whatso-
REC to begin the operation specified in bits 0-1. However, the ever on the 80-column display.
start of the operation can be deferred. If bit 4 of this register is One interesting consequence of the fact that the REC uses
set to % 1 , the DMA process begins immediately when this bit the VIC block setting rather than the configuration register
is set. When bit 4 is %0, the operation does not actually start block setting is that the REC has no trouble seeing the lowest
until the next time a value is stored in location 65280/$FF00 IK of block 1 RAM, which is normally hidden from the pro-
(the MMU configuration register). In this case, the bit remains cessor under the common area from block 0. While bit 6 of the
set to %1 until the operation begins. In either case, the bit is RAM configuration register is set to % 1 , the REC can freely
cleared to %0 once the operation begins. transfer data to and from locations 0-1023/$0000-$03FF in
block 1.
498 499
ADF06 57094
57092 $DF04
wrap from the last address in the last bank to the first address
Both system base address registers are set to 0/$00 during of the first bank. Thus, the REC scarcely notices the bound-
system reset. During REC operations the address in the regis- aries between the expansion memory banks. For verify opera-
ters is usually incremented after each byte is transferred or tions that terminate with a fault (byte mismatch), the registers
verified, so that at the end of the operation the registers will will hold an address which is one location beyond the one at
hold a value one location higher than the last system memory which the mismatch was detected.
address involved in the operation. If the address reaches It is possible to have these registers automatically reloaded
65535/$FFFF, it will roll over to 0/$0000, but the configura- with the starting expansion memory address upon completion
tion will not change (the bank number will not be incre- of an operation. See the entry for bit 5 of the command regis-
mented). For verify operations that terminate with a fault (byte ter at 57089/$DF01 for details of the autoload feature.
mismatch), the registers will hold an address which is one lo- It is also possible to fix the expansion memory address so
cation beyond the one at which the mismatch was detected. that it does not increment. In this case, all bytes in the opera-
It is possible to have these registers automatically re- tion will be read from or written to the same expansion mod-
loaded with the starting system memory address upon com- ule memory location. See the entry below for the address
pletion of an operation. See the entry for bit 5 of the control register at 57098/$DF0A for more information on this
command register at 57089/$DF01 for details of the autoload feature.
feature.
It also is possible to fix the system memory address so 57094 $DF06 DMA BNK
that it does not increment. In this case, all bytes in the opera- Expansion bank register
tion will be read from or written to the same 128 memory lo-
cation. See the entry below for the address control register at This register holds the expansion bank number for REC
57098/$DF0A for more information on this feature. operations.
Bits 0-2: These bits determine the 64K bank of expansion
memory for the address in the registers at 57092-57093/
57092 $DF04 DMA LO $DF04-$DF05. The 1700 module has two 64K banks, so only
57093 $DF05 DMA HI the first two selections are valid for that model. The 1750 has
Expansion memory base address registers eight 64K banks. The possible bank selections are as follows:
This register pair specifies the starting address in the expan- Bits Expansion bank
sion module's address space for the current REC operation. 2 10 0
The first register (57092/$DF04) holds the low byte and the 0 0 0 1
second (57093/$DF05) holds the high byte. The expansion 0 0 1 2
memory bank in which this address is seen is determined by 0 10 3
O i l 4
the value in the expansion bank register at 57094/$DF06. 10 0 5
Both registers are set to 0/$00 during system reset. Dur- 1 0 1 6
ing REC operations the address in the registers is usually in- 1 1 0 7
cremented after each byte is transferred or verified, so that at 1 1 1
the end of the operation the registers will hold a value one lo- tf all the bytes involved in a REC operation are located within
cation higher than the last expansion memory address in- one bank, this register will still hold its original value after the
volved in the operation. When the address in these registers operation is completed. However, when the value in the expan-
exceeds 65535/$FFFF, the address wraps to 0/$0000, but the sion address register rolls over from 65535/$FFFF to 0/$0000,
expansion bank register is also incremented. For example, the the value here will be incremented, unless this register already
next byte after 65535/$FFFF in bank 3 of expansion RAM will
come from location 0/$0000 in bank 4, The address will also
501
500
57095 $DF07 6PF0A 57098
holds the highest bank number. In that case the bank number 57088/$DF00 signals when the REC has generated an IRQ,
will be reset to 0. These bits are reset to %000 when the com- and bits 5-6 of that register indicate which condition caused
puter is reset. the interrupt. After being set to % 1 , the bits in this register re-
Bits 3-7: Unused. Writing to these bits has no effect. The bits al- main set until specifically cleared. Thus, once REC interrupts
ways return %1 when read, so the value returned when this reg- are enabled, they remain enabled until at least bit 7 of this
ister is read will always be at least 248/$F8. To get the true bank register is reset to %0. Bits 5-7 are all reset to %0, disabling
number when reading the register, you should mask off these interrupts, when the system is reset.
bits. (Use AND 3 in BASIC or AND #$03 in machine language.) Bits 0-4: Unused. Writing to these bits has no effect. The bits
It is possible to have this register automatically reloaded always return %1 when read, which means that the value re-
with the starting bank number upon completion of an operation. turned when this register is read will always be at least 31/$1F.
See the entry for bit 5 of the command register at 57089/ $DF01 Bit 5: Setting this bit to %1 specifies that an IRQ interrupt is
for details of the autoload feature. to be generated when a verify operation terminates because
the bytes being compared do not match. However, no inter-
rupt will occur unless bit 7 of this register is also set to % 1 .
57095 $DF07 DMA DAL Bit 6: Setting this bit to %1 specifies that an IRQ interrupt is
57096 $DF08 DMA DAH to be generated if the current REC operation is completed
Count of bytes to transfer without errors, the end-of-block condition. However, no inter-
This pair of registers holds the number of bytes to be trans- rupt will occur unless bit 7 of this register is also set to % 1 .
ferred or verified in the current operation. The first register
(57095/$DF07) is the low byte of the count, and the second Bit 7: Setting this bit to %1 allows IRQ interrupts to be gener-
(57096/$DF08) is the high byte. As each byte is transferred or ated on either of the conditions specified in bits 5-6. No inter-
verified, the value in these registers is decremented. The regis- rupt will occur unless this bit is set, regardless of the settings
ters will always hold the value 1 ($01 $00) after an operation of bits 5-6. However, setting this bit to %1 won't produce in-
is successfully completed. If a verify operation stops because terrupts unless one or both of bits 5-6 are also set to % 1 .
of a fault (byte mismatch), the value in the registers will be Changing this bit to %0 does not affect the setting of bits 5-6.
the original value minus the number of bytes which have been
successfully verified when the fault occurs. All bits in these 57098 $DF0A DMA VER
registers are set to %1 (equivalent to a byte count of 65535/ Address control register
$FFFF) during system reset. Bits 0-5: Unused. Writing to these bits has no effect. The bits
It is possible to have these registers automatically re- always return %1 when read, which means that the value re-
loaded with the starting byte count upon completion of an op- turned when this register is read will always be at least 63/$3F.
eration. See the entry for bit 5 of the command register at Bits 6-7: These bits control the incrementing of the base ad-
57089/$DF01 for details of the autoload feature. dress registers. The four possible settings are as follows:
Bits
57097 $DF09 DMA SUM 7 6 Address register status
Interrupt control register 0 0 Both addresses increment
The REC can generate an 8502 IRQ interrupt on two condi- 0 1 Only the system (128) address increments
tions: When a byte mismatch is detected during a verify oper- 1 0 Only the expansion memory address increments
ation and when all bytes have been successfully transferred or 1 1 Neither address increments
verified. No IRQ will be generated unless bit 7 and one or
both of bits 5-6 are set to % 1 . Bit 7 of the status register at
502 503
57099-57119 $DFOB-$DF1F 53248-57343
$D000-$DFFF
57120-57343 $DF20-$DFFF
REC chip register images Figure 8-18. Typical Character Pattern
Due to incomplete address decoding, images of the REC chip % 00111100 •» 53C
registers appear repeatedly every 32 locations throughout the % 01100110 - S66
remainder of this page of memory. That is, storing a value in % 01101110 - $6E
any location in this range with an address an exact multiple of Vn 01101110 - $6E
32 greater than one of the REC register base addresses has the % 01100000 - $60
same effect as storing that value in the base register location. % 01100010 - S62
For example, the effect of storing a value in 57121/$DF21 or % 00111100 = $3C
57313/$DFE1 is the same as storing the value in 57089/ % oooooooo = $00
$DF01. However, it's better programming practice to use the
officially designated register addresses.
504 505
53248-57343 $DOOO-$DFFF fer>O00-$DFFF 53248-57343
For the VIC chip, this character ROM is the normal source 100 BANK 14:CA = 53248:CS = 8192
of character data. Bits 1-3 of the VIC register at 53272/$D018 110 FOR 1=0 TO 2047
control which 2K block within the current 16K VIC video bank 120 POKE CS + LFEEK(CA+D
is seen as the character source. Since the VIC's default video 130 NEXT I
bank 0 corresponds to locations 0-16383/$0000-$3FFF in the To copy the lowercase/uppercase set, change the value of the
processor's address space, it would seem impossible for the variable CA to 55296. The following routine shows one
character ROM at 53248/$D000 to be used as the normal char- method for accomplishing the same thing in machine language:
acter source. However, the 128's memory manipulation ca- 1400 LDA #$08 ;number of 256-byte pages
pabilities are used to make the ROM appear to the VIC at an 1402 STA $FA ; to be copied
address within the video bank. The uppercase/graphics set ap- 1404 LDA #$00 ;load pointer at $FB with
pears at 4096-6143/$1000-$17FF and the lowercase/uppercase 1406 STA $FB ; target address ($2000)
set appears at 6144-8191/$1800-$lFFF. Only the VIC chip 1408 LDA #$20
sees the character ROM at those addresses; when the MMU 140A STA $FC
configuration register is set to allow the microprocessor to see 140C LDA #$00 ;load pointer at $FD with
the ROM, the processor always sees it at 53248/$D000. The 140E STA $FD ;source address ($D000)
VIC chip, on the other hand, never sees the ROM at its actual 1410 LDA #$D0
1412 STA $FE
address. That couldn't be possible; remember, the VIC itself 1414 LDY #$00 initialize offset
resides at 53248-53296/$D000-$D030. 1416 LDX #$0E ;read from bank 14
The VIC can see the character ROM in any of its four 1418 LDA #$FD ;use $FD as source pointer
video banks. In each case, the uppercase/graphics set appears 141A JSR $FF74 ;Kernal INDFET routine
to the VIC at an offset of 4096/$1000 from the starting ad- 141D STA ($FB),Y ;store in target address area
dress of the video bank, and the lowercase/uppercase set ap- 141F INY
pears at an offset of 6144/$1800 from the first address of the 1420 BNE $1416 ;repeat for 256 bytes per page
video bank. It is possible to disable the ROM image feature so 1422 INC $FC
1424 INC $FD ;increment page pointers
that the VIC never sees character ROM at all. This would be
useful, for example, if you wished to place a custom character 1426 DEC $FA
1428 BNE $1414 ;decrement block count
set in the free RAM at 6144-7167/$1800-$1BFF. Bit 2—called
142A RTS
the CHREN bit—in the 8502's on-chip I/O port at location
l/$01 determines whether or not the ROM image is visible in Refer to the discussion of the VIC chip earlier in this chapter
the current VIC video bank. See Chapter 2 for more infor- for more information on creating and using custom character sets.
mation on the I/O port bit and its associated shadow location, As mentioned, this ROM indirectly supplies character pat-
217/$D9. terns for the VDC (8563) 80-column video chip. That chip has
When setting up custom character sets, you may want to no character ROM of its own, so the contents of this ROM are
copy all or part of the character pattern data from this area of copied into the VDC's private block of RAM during the reset
ROM into RAM. Remember that the only standard bank con- sequence (see the INIT80 routine [$CE0C] in Chapter 7). Refer
figuration in which character ROM is visible is bank 14, The to the section on the VDC earlier in this chapter for more
following BASIC lines will copy the uppercase/graphics set information on how the 80-column character set is managed.
into RAM at 8192-10239/$2000-$2800. (You must have pre-
viously protected this area from BASIC. Using GRAPHIC
1:GRAFHIC 0 to reserve the bitmapped screen area is a simple
way to do this.)
506 L 507
Kernal ROM
In software engineering jargon, the collection of subroutines
that perform basic input and output functions for a computer
is referred to as the operating system kernel. The developers
of the kernel for the original Commodore PET spelled (or mis-
spelled) the term as kernal, and Commodore operating systems
have been referred to as the Kernal ever since. There are both
similarities and significant differences between the 128 Kernal
and the Kernals of earlier models.
The Kernal handles input from or output to five basic
sources: the keyboard, the video screen, the tape drive (Datas-
sette), the RS-232 port, and the serial bus (to which disk
drives and printers are connected). In the 128 Kernal, all key-
board and video functions have been transferred to a separate
block of ROM, the screen editor, at 49152/$C000 (see Chapter
7 for details).
Significant enhancements include the addition of an 80-
column screen, ESC-key screen-editing sequences, and key-
board table pointers in RAM that make it easy to customize
the keyboard. Tape and RS-232 support is largely unchanged
from that provided in the Commodore 64 Kernal. Serial bus
operation is significantly enhanced by the addition of a new
fast serial mode which can transfer data much more quickly
than the old system, now fittingly referred to as slow serial
mode.
Additional new features of the 128 Kernal include routines
to handle the storage, retrieval, and comparison of data from
the various memory banks supported by the system, and sup-
port for DMA (Direct Memory Access) transfer operations to
and from the 1700 and 1750 Memory Expansion Modules.
The heart of the Kernal is the collection of routines called
by the Kernal jump table at 65409-65525/$FF81-$FFF5. The
routines called from that table, and their supporting subrou-
tines, make up the bulk of the Kernal and provide access to
the majority of the 128's input/output (I/O) capabilities. Al-
most any I/O operation can (and should) be performed
through the appropriate jump table entry. The Kemal jump ta-
ble has been a feature of all Commodore operating systems.
511
57344 8E000 SE04B 57419
The 128 adds an additional jump table with 19 new entries at initialization flag (2562/S0A02) is checked. If the flag contains
65351-65407/$FF47-$FF7E These entries provide access to a nonzero value, the following memory initialization step is
most of the 128 Kernal's new or enhanced features, skipped. Since the flag is given the value 165/SA5 after the
first call to RAMTAS [$E093], zero-page values and memory
57344 $E000 RESET pointers are preserved if RUN/STOP is held down during a
Performs main system initialization sequence. subsequent reset. Otherwise, RAMTAS [$E093] is called to
Resets the processor stack pointer to the top of the stack, dis- clear all zero-page RAM locations and reestablish Kernal
ables IRQ interrupts, and insures that the processor is not in pointers.
decimal mode; then sets the MMU configuration register for RESTOR [$E056] is called to load default Kernal indirect
bank 15. Other MMU registers are initialized from the table at vectors into 788-819/$0314-$0333. CINT [$CO0O] is called to
57419/$E04B. Next, the initialization status flag (2564/$0A04) initialize the screen editor, after which IRQ interrupts are once
is reset to 0/$00 to indicate that all variables and vectors need again allowed. If the RUN/STOP key has been pressed, the
to be initialized. The interrupt and reset handling routines at monitor is entered through its cold start entry point [$B000]. If
65285-65348/$FF05-$FF44 in Kernal ROM are copied to that the Commodore key has been held down, 64 mode is entered
same area in all RAM banks, and the INDFET, INDSTA, using the C64_MODE routine [$E24B], Otherwise, BASIC 7.0
INDCMP, J5RFAR, JMPFAR, and DMA_CALL routines are is entered via the restart vector at 2560/S0A00. If the
copied from the table at 63488/$F800 into bank 0 RAM. RAMTAS step has been performed, the restart vector will
Locations 65525-65527/$FFF5-$FFF7 in bank 1 are then point to BASIC'S cold start entry point [$4000].
examined to see if they contain the character codes for the let- It is possible to perform most of the reset sequence with-
ters CBM, If not, those locations are initialized with that char- out losing the BASIC program currently in memory. Simply
acter pattern, and the soft reset vector at 65528/$FFF8 in bank hold down RUN/STOP while pressing the RESET button,
1 is initialized. However, if the test pattern is found (indicating This will skip the RAMTAS step, which would wipe out im-
that RESET has already been performed at least once), the portant program pointers. You will land in the monitor after
routine jumps to the address in the vector. Normally, the vec- the reset; type X to exit to BASIC, where the current program
tor points to the routine at 57892/$E224, which simply should still be intact.
reinitializes the test pattern and vector. You can change the Note that the reset routine does not explicitly attempt to
address to add your own extra steps to the reset sequence. See boot a disk or to initialize function ROMs that are not
the soft reset vector entry in Chapter 4 for details. autostarting. These tasks are performed by the Kernal PHOE-
The subroutine at 57922/$E242 is called to check for the NIX routine [$F867]. In 128 ROM, PHOENIX is called only
presence of a Commodore 64 cartridge. If one is detected, the during the BASIC cold start routine [$4023]. However, as long
system is switched to 64 mode and the computer becomes a as the RUN/STOP or Commodore key is not held down, the
Commodore 64. (You must press the RESET button or turn reset routine ends by jumping to the BASIC cold start routine,
the computer off and back on to return to 128 mode.) Other- so those actions are implicitly part of the normal reset
wise, the subroutine records the presence of any 128 function sequence.
ROMs in the table at 2753-2756/$0ACl-$0AC4. If a logged
function ROM is autostarting, its cold start routine is called. It 57419 $E04B
is possible that an autostarting ROM will retain control of the Table of default MMU register settings.
system and will not return to complete the reset sequence. The 11 values in this table are copied into the MMU chip reg-
Next, the IOINIT routine [$E109] is called to initialize the isters at 54528-54538/$D500-$D50A by the system reset rou-
video, CIA, and SID chip registers. The keyboard column tine [$E000]. See Chapter 8 for details of the function and
which includes the RUN/STOP and Commodore keys is default settings of the registers.
scanned. If RUN/STOP has been pressed, the Kernal memory
512 513
57430 SE056 SE109 57609
separate versions of the Kernal for North American and Euro- numbers and initializes registers until a value greater than
pean 128s. 127/$7F is read for the register number. Normal X register
Next, a number of Kerna! I/O flags are cleared: clock values upon entry are 0/$00 (to initialize the 8563), 59/$3B
mode storage (2615/$0A37), IRQ vector storage (2570/$0A0A), (to adjust horizontal scrolling for different versions of the 8563
custom mode setting (2618/$0A3A), and jiffy count com- chip), or 62/S3E (to adjust register settings for a PAL video
pensation (2614/$0A36), The keyboard (device 0) is made the system).
current input device (153/S99), and the screen (device 3) is
made the current output device (154/$9A).
57840 $E1FO
VIC-II chip registers (53248-53296/$D000-$D030) are Initializes or jumps through the soft reset vector.
initialized from the table at 58055/$E2C7, and 8563 video
Examines the contents of locations 65525-65527/$FFF5-$FFF7
chip registers are initialized using the subroutine at
in bank 1 to determine whether those locations contain the
5782O/$E1DC. If the version number of the 8563 chip (bits
character codes for the letters CBM. If not, a branch is taken to
0-2 of the register at 54784/$D600) indicates that one of the
newer revisions of that chip is installed, the subroutine is the following routine to initialize the test pattern and vector. If
called again to adjust the horizontal scrolling register (R25). If the pattern is found, the reset vector has already been initial-
the PAL video system is in use, the subroutine is called yet ized, so the address in the vector at 65528-65529/$FFF8-$FFF9
again to adjust vertical display registers (R4 and R7). Bit 7 of in bank 1 is loaded into locations 2-3/$02-$03. The routine
the initialization status flag (2564/$0A04) is tested. If the bit is then takes an indirect jump to the specified address. (The sys-
set to % 1 , IOINIT has been called at least once before, so the tem will still be configured for bank 15, so the target routine
following step, which sets up the 80-column character set, is must in that bank.)
skipped. If the bit is %0 (as will normally be the case when
this routine is called as part of the reset sequence), the screen 57892 $E224
editor INIT80 routine [$C027] is called to copy the ROM char- Initializes the soft reset vector.
acter definitions into 8563 RAM. Then bit 7 of the initializa- Loads the system soft reset vector, locations 65528-65529/
tion status flag will be set to %1 to indicate that the step has $FFF8-$FFF9 in bank 1, with the value 57892/$E224, the ad-
been performed. dress of this routine. Next, the character codes for the letters
All registers for the SID sound chip (54272-54296/ CBM are copied to locations 65525-65527/$FFF5-$FFF7 in
$D400-$D418) are cleared to zero to disable any sound out- bank 1 to indicate that the vector has been initialized.
put; then VIC-II raster interrupts are enabled. The raster inter-
rupt (set by the default table value to occur at scan line 255) is 57922 $E242
the normal source of jiffy IRQ interrupts for the 128. The fast Checks for the presence of 64 cartridges or 128 function ROMs.
serial flag (2588/$0AlC) and RS-232 activity flag (2575/ Tests the GAME and EXROM lines from the memory expan-
$0A0F) are cleared to zero. Timer B of CIA #1 is loaded with sion port (reflected by bits 4 and 5 of the MMU mode configu-
65535/$FFFF and started counting continuously. Finally, a fast ration register at 54533/$D505). If either of the lines is
serial mode setup sequence is performed. grounded, the routine falls through to enter 64 mode. Other-
wise, a branch is taken to the routine at 57963/$E26B to
57820 $E1DC check for 128 function ROMs.
Initializes 80-column video chip registers.
Retrieves a byte from the position in the table at 58104/$E2F8 57931 $E24B C64_MODE
specified in the X register. The value is used as a register num- Switches the system into 64 mode.
ber and the next value in the table is written to that 8563 reg- (This routine has a jump table entry at 65357/$FF4D.)
ister, Once called, the routine repeatedly reads register Loads the processor data direction and I/O port registers
(locations 0-l/$00-$01) with their standard Commodore
516 517
57963 $E26B 58174
SE33E
519 519
58174 SE33E 6E38C 58252
capable of fast serial communications is present, it should re- Next, the serial bus ATN line is pulled low to indicate
spond by sending back a byte. This will cause a serial register that the following byte will be a command. The serial bus
interrupt on CIA # 1 , which will be detected later to determine CLK line is pulled low, and the DATA line is allowed to go
that fast serial mode is available. high. A delay loop of approximately one millisecond is exe-
cuted, and the routine falls through into the following routine
to send the command byte. Figure 9-1 illustrates the process.
Figure 9-1. Sending a Serial Command Byte Note that there is no corresponding routine for the 128
to receive a serial bus command. The 128 has no ATN input
line, so it cannot be commanded to listen (it only listens "vol-
untarily"). It must always be the only master device on the se-
rial bus.
58252 SE38C
Sends buffered byte to a serial device.
Begins by calling the subroutine at 58739/$E573 to disable
IRQ interrupts and standardize timing. If the system is set for
the fast {2 MHz) clock mode, it will be temporarily reset to the
normal (1 MHz) mode, which explains why serial communica-
1. 128 pulls ATN line low. tions are not significantly affected by the clock mode.
2. 128 pulls CLK line low and allows the DATA line to go high. The routine makes sure that the serial bus DATA line is
3. The external device must respond by holding the DATA line low. free to go high, then tests the state of the line. If the external
If the DATA line is still high after approximately one millisecond, device is not holding DATA low, the device is considered not
it is assumed that the device is not present. present, so bit 7 of the serial status flag (144/$90) will be set
4. If the external device responded, the 128 allows the CLK line to to % 1 , the ATN and CLK lines will be allowed to go high, and
go high. the routine will exit. Otherwise, the routine will allow the CLK
5. The external device must now allow DATA to go high again. (The line to go high. If bit 7 of the EOI flag (163/$A3) is set to % 1 ,
128 will wait indefinitely for this to happen.) the routine performs the EOI (end-or-identify) handshake by
6. Once DATA goes high, the 128 responds by pulling the CLK line waiting for the external device to set the DATA line high and
low. then low. Next, the routine waits for the external device to re-
7. The command byte is then sent one bit at a time, starting with the lease the DATA line to a high state. While it's waiting, the
least significant bit (bit 0). Command bytes are always sent in routine checks whether a CIA #1 serial register interrupt has
slow serial mode. To send a bit, the DATA line is set either low or occurred, indicating that a byte has been received via the fast
high, depending on whether the bit being sent is %0 or % 1 . Then
the CLK is allowed to go high briefly to signal that a valid bit can serial hardware. If so, the external device can accept fast serial
be read on the DATA line. input, and the fast serial flag (2588/S0A1C) is set to 192/$C0
8. After the last data bit is sent, the 128 checks the DATA line. The to indicate this.
external device must pull that line low within approximately one Once the DATA line goes high, the routine immediately
millisecond or a write-timeout error will be indicated. pulls the CLK line low and proceeds to send the byte of data.
9. The status of the ATN line after a command is sent depends on If fast serial mode is available, the process is simple: The serial
the command. If it is TALK or LISTEN, ATN remains high so that port is set for fast serial output, and the buffered byte from
the secondary address can be sent as a command as well. How- 149/$95 is stored in the CIA #1 serial data register (56332/
ever, ATN is immediately pulled low following UNTALK and $DC0C). After that, the transfer is automatic, handled by the
UNLISTEN commands.
520 521
v
58252 SE38C SE38C 58252
CIA chip hardware. The routine simply waits until a serial reg- allowed to go high again. If the external device holds the
ister interrupt indicates that the byte has been completely sent, DATA line low between bits, a write-timeout occurs (the rou-
then resets the port for fast serial input (its default state). tine sets bits 0 and 1 in the serial status flag to % 1 , allows the
The process for sending a byte in standard (slow) serial ATN and CLK lines to go high, and exits).
mode is more complicated because it is handled in software. After the byte has been sent (in either mode), the routine
Bits are pulled from the buffered byte (149/$95), one at a waits for the external device to pull the DATA line low. If this
time, starting with the least significant tit (bit 0). For each bit, does not happen within approximately one millisecond, a
the serial bus DATA output line is set either high or low, de- write-timeout occurs, and the routine sets bits 0 and 1 in the
pending on whether the bit to be sent is %0 or % 1 . Then the serial status flag to % 1 , allows the ATN and CLK lines to go
CLK line is allowed to go high to signal to the external device high, and exits. Otherwise, the routine at 58783/$E59F is used
that a valid data bit can be read from the DATA line. After a to restore interrupts and the clock mode setting, then exits
brief delay, the CLK line is pulled low, and the DATA line is with the status register carry bit clear. The Y register is unused
during the routine, and the X register value is preserved. Fig-
ure 9-2 illustrates the process of sending a data byte. Figure
Figure 9-2. S e n d i n g a Serial Data Byte 9-3 illustrates the EOI handshake.
1. The 128 allows the DATA line to go high. If the external device
does not continue to hold the line low, it is assumed that the de-
vice is not present.
2. The 128 allows the CLK line to go high.
200 \is.
3. The external device must now allow DATA to go high. (The 128
will wait indefinitely for this to happen.) 1. As in a normal byte transfer, the external device must hold the
4. Once DATA goes high, the 128 responds by pulling the CLK line DATA line low or it will be assumed that the device is not
low. present.
5. The data byte is sent one bit at a time using either fast or slow se- 2. The 128 allows the CLK line to go high.
rial mode. To send a bit in slow serial mode {illustrated above), 3. The external device should then allow the DATA line to go high.
the DATA line is set either low or high, depending on whether the (The 128 will wait indefinitely for this to happen.)
bit being sent is %0 or % 1 . Then the CLK line is allowed to go 4. When the 128 does not respond by pulling the CLK line low
high briefly to signal that a valid bit can be read on the DATA within 200 microseconds, the external device should recognize
line. Fast serial mode works in a similar manner, except the trans- that an EOI handshake is being performed and should respond by
fer is managed by CIA chip hardware rather than ROM software, pulling DATA low again. (The 128 will wait indefinitely for DATA
and the bits are clocked by pulses on the SRQ line rather than on to go low.)
the CLK line, 5. The external device should then release DATA high again. The
6. After all of the byte is sent, the 128 checks the DATA line. The ex- 128 will respond by pulling CLK low, and the final byte of the file
ternal device must pull that line low within approximately one is then sent in the usual manner. (See steps 5-6 of Figure 9-2.)
millisecond, or a write-timeout error will be indicated.
522 523
58430 6E43E SE43E 58430
58430 8E43E ACPTR is preserved. Figure 9-4 illustrates the process of receiving a
Reads a byte from a serial device. data byte.
(This routine has a jump table entry at 65445/$FFA5.)
Begins by calling the subroutine at 58739/$E573 to disable Figure 9-4. Receiving a Serial Data Byte
IRQ interrupts and standardize timing. If the system is set for
the fast (2 MHz) clock mode, it will be temporarily reset to the
normal (1 MHz) mode, which explains why serial communica-
tions are not significantly affected by the clock mode. The rou-
tine insures that the serial bus CLK line is free to go high,
then tests the state of the line and waits in a loop until it goes
high. Next, a delay counter is initialized, and the DATA line is
allowed to go high. If the external device responds by pulling
the CLK line low before the delay count expires, the routine
begins to process the incoming data bits. Otherwise, it assumes
that the external device is requesting an EOI (end-or-identify)
handshake. So the EOI bit (bit 6) of the serial status flag
(144/$90) is set to % 1 , and the DATA line is pulled low, then
allowed to go high again. The external device must acknowl- 1. The 128 allows the CLK line to go high and waits for it to go high
edge the EOI handshake by pulling the CLK line low before if the external device is holding it low.
another delay period expires. If it doesn't, a read-timeout oc- 2. Once the CLK line goes high, the 128 allows the DATA line to go
high.
curs, and the routine sets bit 1 in the serial status flag to % 1 , 3. The 128 waits for the external device to respond by pulling the
allows the ATN and CLK lines to go high, and exits. CLK line low. If this hasn't happened after a delay of approxi-
If a serial register interrupt has occurred on CIA #1, a mately 260 microseconds, the 128 assumes that an EOI handshake
byte has been received via the fast serial hardware. In this is requested and briefly pulls the DATA line low. The external
case, the byte is retrieved from the serial data register device must respond by pulling CLK low before another 260-
(56332/$DC0C) and stored in 164/$A4; then the fast serial microsecond delay expires; otherwise, a read-timeout error will
flag (2588/$0AlC) is reset to 192/$C0. occur,
The process for receiving a byte in standard (slow) serial 4. Once the CLK line goes low, the 128 prepares to read data. To re-
mode is more complicated because it is handled in software. ceive a bit in slow serial mode (illustrated above), the 128 waits
The routine waits for the data line to go high and then for the until the CLK line goes high, reads the CIA port bit connected to
CLK line to go low. Then, when CLK goes high again, a bit is the DATA input line, then waits for the CLK line to go low again.
Fast serial mode works in a similar manner, except the transfer is
read from the DATA line and shifted into the working byte managed by CIA chip hardware rather than ROM software, and
(164/$A4). The routine waits until CLK goes low before at- the bits are clocked by pulses on the SRQ line rather than the
tempting to read the next bit, and the process is repeated for CLK line.
each of the eight bits of the byte. 5. After the byte is received, the 128 pulls the DATA line low to in-
After a byte has been received, the DATA line is pulled dicate the end of the byte frame.
low to mark the end of the frame. If the EOI handshake has 6. If the EOI handshake is performed, the CLK line is allowed to go
been performed, the CLK line is allowed to go high. The rou- high after the byte is received.
tine at 58783/$E59F is used to restore interrupts and the clock
mode setting. The routine exits with the status register carry
bit clear and with the received byte in the accumulator. The Y
register is unused during the routine, and the X register value
524 525
58578 $E4D2 AE515 58645
58583 $E4D7
Allows the serial bus ATN output line to go high. 1. The 128 holds the DATA line low and allows the ATN line to go
Forces bit 3 of CIA #1 port A to %0. Since that bit is con- high.
nected to the serial bus ATN output line via an inverter, this 2. The 128 allows the CLK line to go high.
will set the ATN output line to a high state ( + 5 volts). 3. The external device must respond by pulling CLK low, (The 128
will wait indefinitely for this to happen.) The external device is
now the talker and the 128 is the listener.
58592 $E4E0 TKSA
Sends secondary address after TALK.
(This routine has a jump table entry at 65430/$FF96.) 58627 $E503 CIOUT
Sends a byte to a serial device.
Stores the secondary address value from the accumulator into (This routine has a jump table entry at 65448/$FFA8.)
the serial byte buffer at 149/$95, then sends the buffered byte
Tests bit 7 of the serial buffer flag (148/S94). If the bit is %0,
as a command (the ATN line should still be high from the
indicating that the one-byte serial buffer (149/$95) is empty,
previous TALK command). If the device is not present, the
the byte in the accumulator is simply stored in the buffer and
routine exits (after allowing the ATN and CLK lines to go high
the flag bit is set to %1 before exiting. However, if the flag bit
again). Otherwise, the routine falls through into the next one
is already % 1 , a character is currently waiting in the buffer. In
to make the 128 the listener and recognize the external device
this case, the routine at 58252/$E38C is used to send the pre-
as the talker,
viously buffered character before the new character is added to
the buffer. Carry will always be clear upon exit, and the byte
58601 $E4E9
value will still be in the accumulator. The X and Y register val-
Performs talk-listen turnaround.
ues are also preserved. The success of the operation can be de-
Begins by calling the subroutine at 58739/SE573 to disable termined from the value in the serial status flag (144/$90).
IRQ interrupts and standardize timing. The DATA line is held The purpose of the buffering scheme is to make it possible to
low, and the ATN line is allowed to go high (signaling the perform the EOI (end-or-identify) handshake with the final
end of the command). The CLK line is then allowed to go character of a file,
high. The device which is commanded to talk should respond
by pulling CLK low. The routine waits for this to happen, then 58645 $E515 UNTLK
jumps to the routine at 58783/$E59F to restore interrupts and Sends UNTALK command to a serial device.
the clock mode. Figure 9-5 illustrates the talk-listen (This routine has a jump table entry at 65451/$FFAB.)
turnaround. Begins by calling the subroutine at 58739/$E573 to disable
IRQ interrupts and standardize timing. The CLK line is pulled
low; then ATN is pulled low as well to indicate that the byte
526 527
58662 $E526 SE573 58739
will be a command. The accumulator is loaded with the UN- 58720 $E560
TALK command value, 95/$5F. Then a BIT opcode is used to Pulls serial bus DATA output line low.
fall through into the next routine to send the byte as a com- Sets bit 5 of CIA #2 port A to % 1 . Since the output line for
mand. Unlike TALK, which affects only a specified serial de- that port bit is connected to the serial bus DATA output line
vice, UNTALK affects all serial devices. However, this shouldn't
cause problems because the 128 serial bus allows only one ac- via an inverter, this will set the output line to a low state (0
tive talker at any given time. volts).
58729 $E569
58662 8E526 UNLSN Reads the serial bus DATA and CLK input lines.
Sends UNLISTEN command to a serial device.
(This routine has a jump table entry at 65454/SFFAE.) Reads the value at port A of CIA #2, then shifts the value of
bit 7, connected to the serial bus DATA input line, into the
Loads the accumulator with the UNLISTEN command value, status register carry bit. This will also shift the value of bit 6,
63/$3F, then clears bit 7 of the serial mode flag (2588/$0AlC) connected to the CLK input line, into bit 7. Upon return, the
to disable fast serial mode, and sends the byte in the accumu- DATA bit can be tested with BCC/BCS or shifted into a work-
lator as a command on the serial bus. Afterward, the ATN line ing byte, and the CLK bit can be tested with BPL/BMI.
is allowed to go high (signaling the end of the command), and,
after a short delay, the CLK and DATA lines are allowed to go 58739 $E573
high as well. Unlike LISTEN, which affects only a specified se- Disables IRQ interrupts and standardizes timing during I/O
rial device, UNLISTEN affects all serial devices. However, this operations.
shouldn't cause problems because the 128 serial bus normally
has only one listener at any given time. Begins by disabling IRQ interrupts. Next (at 58740/$E574), the
custom mode flag (2618/S0A3A) is checked. If bit 7 of this
flag is set to % 1 , the routine exits without changing the clock
58693 $E545 mode setting or disabling sprites. The 128 sets this flag to zero
Allows serial bus CLK output line to go high. during the IOINIT routine (part of both the reset and
Sets bit 4 of CIA #2 port A to %0. Since the output line for RUN/STOP-RESTORE sequences) and does not normally
that port bit is connected to the serial bus CLK output line via change the value. You can set bit 7 of the flag if for some rea-
an inverter, this will set the output line to a high state ( + 5 son you want to retain fast clock mode or sprites during an
volts). I/O operation. The clock mode storage flag (2615/$0A37) is
then checked. The routine exits if bit 7 of this flag is set to
58702 $E54E % 1 , indicating that a clock mode has already been stored (bits
Pulls serial bus CLK output line low. 2-7 of $D030 are always %1). Otherwise, the value in the
Sets bit 4 of CIA #2 port A to % 1 . Since the output line for VIOII register at 53296/SD030, which determines the system
that port bit is connected to the serial bus CLK output line via clock frequency, is stored in the clock mode flag, and the
an inverter, this will set the output line to a low state (0 volts). value in the register at 53269/$D015, which determines which
sprites are currently enabled, is stored in 2616/$0A38. Both
58711 $E557 registers are then reset to zero, which disables all sprites and
Allows serial bus DATA output line to go high. sets the system to normal (1 MHz) clock speed. This is done to
Sets bit 5 of CIA #2 port A to %0. Since the output line for standardize system timing. Tape and serial data transfers rely
that port bit is connected to the serial bus DATA output line on software delay loops for critical timing functions, so the
via an inverter, this will set the output line to a high state system must be in a standard mode for the loops to provide
( + 5 volts). the correct delay. If any sprites have previously been enabled,
a delay loop is executed before the routine exits.
528
I 529
58783 $E59F SE61B 58907
make the total odd. If even parity is specified, a parity bit of is loaded from 2581/S0A15. Tf the RS-232 output buffer is
%0 will be prepared when the parity flag indicates that the empty, the routine disables timer A interrupts and exits. Oth-
number of %1 bits already sent is even, and a parity bit of %1 erwise, the next available byte from the output buffer is
will be prepared when the number of %1 bits sent is odd so loaded into 182/$B6, and the pointer to the head of the buffer
that the total number of %1 bits sent (including the parity bit) (2586/S0A1A) is incremented,
will always be even. Mark and space parity are simpler: In the
former case, the parity bit is always % 1 ; in the latter, it's al- 59007 $E67F
ways %0. (Early versions of the Commodore 64 Kernal incor- Sets CIA interrupt register and RS-232 activity flag.
rectly computed even and odd parity. All types of parity are Sets or clears bits in the interrupt control register for CIA #2,
handled properly in the 128 Kernal and in the version of the depending on the value in the accumulator. If bit 7 of the ac-
Commodore 64 Kernal used for 64 mode in the 128.) cumulator value is %0, the interrupt register bits correspond-
Next, the routine prepares for the transmission of either ing to the %1 bits in the accumulator value will be cleared. If
one or two stop bits, depending on the setting of bit 7 of the bit 7 is % 1 , the interrupt register bits corresponding to any
RS-232 control register (2576/$0A10). If one stop bit is speci- other %1 bits in the accumulator value will be set. The RS-232
fied (if the register bit is %0), the count of bits remaining to be activity flag (2575/$0A0F) is then updated to reflect the new
sent (180/$B4) is decremented once {to 255/$FF). If two stop setting of the interrupt register.
bits are sent (if the register bit is %1), the count is
decremented twice (to 254/$FE). The routine ends by branch- 59022 $E68E
ing back into the previous routine to set the prepared parity or Computes bit count for the RS-232 operation.
stop bit as the next bit to send. Computes a bit count based on the setting of bits 5 and 6 of
the RS-232 control register (2576/$0A10). The count value,
58948 $E644 which will be one greater than the number of data bits speci-
Prepares to send a stop bit. fied, will be returned in the X register.
Increments the count of bits remaining to be sent (180/$B4), Bits Data bits Bit count
then prepares a %1 bit for transmission (stop bits are always 6 5
%1). 0 0 8 9
0 1 7 8
1 0 6 7
58954 SE64A 1 1 5 6
Prepares to transmit next byte.
Checks bit 0 of the RS-232 command register (2577/$0All) to 59037 $E69D
determine which handshaking mode is in use. If x-line Processes received bits.
handshaking is specified (if the register bit is %1), the RS-232 Checks the start bit flag (169/$A9) to determine whether the
DSR and CTS lines (pins K and L of the user port) are tested. start bit for a byte has been read yet. If not, a branch is taken
If the external device is not holding these lines high, the cor- to 59092/$E6D4 to see whether this is a start bit. Otherwise,
responding bit in the RS-232 status flag (2580/$0A14) is set— the received bit count (168/SA8) is decremented. If the count
bit 6 for DSR missing or bit 4 for CTS missing—then the rou- has reached zero, all bits for a byte have been received, so a
tine disables timer A interrupts to halt transmission. branch is taken to 59103/$E6DF to process the byte. Other-
For three-line handshaking, or for x-line handshaking wise, the parity indicator is toggled, and the received bit in
when DSR and CTS are held high, the parity flag (189/SBD) 167/$A7 is shifted into the work byte (170/$AA).
is cleared and the current bit flag (181/$B5) is set to 0/$00
(start bits are always %0). The count of bits to send (180/$B4)
533
532
59058 $E6B2 59228
SE75C
59058 $E6B2 the received character is padded with %0 bits if it is less than
Tests for stop bit. eight bits long and then stored at the current tail of the input
Decrements the received bit count and checks whether the re- buffer. If no parity is used, a branch is taken to 59058/$E6B2
ceived bit is a %1 (stop bits are always %1). If it is, bit 7 of to check for a stop bit. Otherwise, the current bit received
the RS-232 control register (2576/$0A10) is tested. If one stop (167/$A 7) is taken to be a parity bit and is compared against
bit is specified (if the register bit is %0), the routine falls the calculated parity for the byte. If the two do not correspond
through into the next one to prepare to receive the next byte. to the specified parity type, the parity error bit (bit 0) of the
If two stop bits have been specified, the routine exits to look status flag will be set, and the routine will jump to reset for
for another stop bit. the reception of the next byte.
If a stop bit has not been received, the routine branches to
set a bit in the serial status flag (2580/$0A14) according to the 59177 SE729
previously received byte (170/SAA): bit 1—the framing error
bit—if the previously received byte is nonzero, or bit 7—the Handles CKOUT for RS-232 device.
break error bit—if the previously received byte is zero (indi- Sets the device number in the accumulator as the current out-
cating that the received data line is being held low). put device (154/$9A), then tests bit 0 of the RS-232 command
register (2577/$0All). If the bit is %0, three-line handshaking
59074 $E6C2 has been specified, so the routine exits at this point. For x-line
handshaking, the routine tests the DSR line (pin L of the user
Prepares to receive next byte. port). If the external device is not holding this line high, a
Enables FLAG interrupts for CIA #1, then updates the RS-232 branch is taken to set bit 6 of the RS-232 status flag (2580/
activity flag (2575/$0A0F) to indicate that FLAG interrupts are $0A14) and exit with the status register carry bit clear. If DSR
active. The nonzero flag value will also be stored in the start is high, the state of the RTS line (pin D of the user port) is
bit flag (169/$A9) to indicate that no start bit has been re- checked. If the 128 previously set this line high, the routine
ceived. Timer B interrupts are then disabled, and the activity exits with carry clear. Otherwise, the routine waits until any
flag is updated to reflect this. (Timer B interrupts, used to time current transmission is completed, then waits for the external
incoming bits, are reenabled after the FLAG interrupt occurs,) device to pull the CTS line (pin K of the user port) low. The
routine then sets the RTS line high to signal that it is ready to
59092 SE6D4 send a byte and waits until an external device sets the CTS
Tests for start bit. line high to acknowledge that it is ready. (If DSR goes low
Tests the received bit (in 16 7/$A 7). If it is not %0, it is not a while the routine is waiting, bit 6 of the status flag will be
start bit, so a branch is taken to 59074/$E6B2 to look for an- set). The routine then exits with carry clear.
other byte. Otherwise, the zero value is stored in the start bit
flag (169/$A9) to indicate that a start bit has been received, 59228 $E75C
and the parity indicator flag (171/$AB) is initialized to 1/S01. Handles BSOUT for RS-232 device.
(The normal entry point for this routine is 59231/SE75F.)
59103 $E6DF Checks whether the output buffer is currently full. If no space
Stores received character in buffer and checks parity. is available, the routine loops to enable interrupts for RS-232
Checks whether space for an additional character is available transmission and waits until space becomes available in the
in the input buffer. If not, the routine branches to set the re- buffer. The buffer tail pointer (2587/$0AlB) is incremented,
ceiver buffer overflow bit (bit 2) in the RS-232 status flag and the value in the accumulator is placed at the tail of the
(2580/$0A14) and to prepare for the reception of the next output buffer. If bit 0 of the RS-232 activity flag (2575/$0A0F)
byte, (The received character is lost in this case.) Otherwise, is set to % 1 , timer A interrupts are already enabled, so the
routine exits at this point. Otherwise, timer A is loaded with
534
1 535
59285 $E795 $E805 59397
Otherwise, a test is made of bit 4 in both the interrupt register 59561 $E8A9
value and the activity flag. If the bit is set in both, a valid
FLAG interrupt has occurred, so the subroutine at 59561/ Initiates reception of RS-232 byte.
$E8A9 is called to start reception of a byte. In either case, the (Called by the NMI handling routine when a FLAG interrupt
activity flag value is stored in the CIA interrupt register to occurs.)
reenable RS-232 interrupts before exiting. Begins by copying the bit timing constant value (2578-2579/
$0A12-$0A13) into the latch for timer B (56582-56583/
59472 $E850 $DD06-$DD07) and starting timer B. Then, FLAG interrupts
Table of baud rate timing constants for NTSC systems. are disabled and timer B interrupts are enabled. The RS-232
activity flag (2575/$0A0F) is updated to reflect the change.
The ten two-byte values in this table (in low-byte/high-byte The latch for timer B is loaded with $FFFF so that the timer
order) are the CIA timer settings used to transmit and receive
bits at the ten standard baud rates when the 128 is operating will count continuously after it counts down for the next bit.
with NTSC clock frequency (1.02273 MHz). This is the for- Finally, the count of bits to be received for the current char-
mula for table values: acter is loaded from 2581/$0A15 into the working counter
(168/SA8).
value = 1.02273E6 / (2 * baud rate) - 100
59492 $E864 59600 SE8D0
Reads next header block from tape.
Table of baud rate timing constants for PAL systems. Calls the subroutine at 59890/$E9F2 to fill the cassette buffer
The ten two-byte values in this table (in low-byte/high-byte with the next block from tape, exiting with the status register
order) are the CIA timer settings used to transmit and receive carry bit set if the RUN/STOP key is pressed while the block
bits at the ten standard baud rates when the 128 is operating is being loaded.
with PAL clock frequency (0.985265 MHz). This is the formula
for table values: The first byte in the header block, the type identifier, is
then examined. If the identifier value is 5, this is an end-of-
value = 0.985265E6 / (2 * baud rate) - 100 tape marker, so the routine branches to exit with carry set (in
this case, the Y register will hold the value 255/$FF). If the
59512 $E878 identifier value is something other than 1, 3, or 4, the routine
Reads a bit from RS-232 device. loops back to read another block. If Kernal messages are al-
(Called by the NMI handling routine when a rimer B interrupt lowed, FOUND is displayed, followed by 16 filename charac-
occurs.)
ters from the buffer. (The buffer is filled with space characters
Reads the current status of the R5-232 received data line (pin when the header is written, so the displayed name will be
C of the user port) and stores the bit value in 167/$A7. The padded with spaces if it is fewer than 16 characters long.) A
interrupt time for the next bit is calculated and stored in the delay loop lasting for two increments of the middle byte of the
timer B latch (56582-56583/$DD06-$DD07); then timer B is jiffy clock (161/$A1), about 8-1/2 seconds, is then started. If
restarted. CIA #2 interrupts are reestablished by storing the the space key is pressed during this delay, the routine loops
RS-232 activity flag (2575/$0A0F) in the interrupt register back to the beginning to read another header. If any other key
(56589/$DD0D), and the timer latch is reloaded with $FFFF. in the same column (for example, Commodore or CONTROL)
The routine ends by jumping to 59037/$E69D to process the is pressed, the loop is terminated. At the end of the loop, the
received bit. routine exits with carry clear. The X register will hold the type
identifier value for the header.
538
539
59673 SE919 $E9DF 59871
540 541
59881 SE9E9 $EA26 59942
register Z bit will be clear if no button is pressed or will be set 59928 $EA18
if any button is detected. Writes a block to tape.
Loads the leader flag (171/SAB) with 20/$14 to specify a
59881 $E9E9 short leader between the header and the block; then calls the
Requests RECORD and PLAY buttons if necessary. subroutine at 59881/$E9E9 to request that the PLAY and
Checks whether a tape button is currently pressed; exits with RECORD buttons be pressed. (The routine will exit with carry
the status register carry and Z bits set if any buttons are al- set if the RUN/STOP key is pressed during the subroutine.)
ready pressed. Otherwise, if Kernal messages are allowed, IRQ interrupts are disabled and the accumulator is loaded with
PRESS RECORD & PLAY ON TAPE is displayed. The routine 130/$82 (the value to enable timer B interrupts), and the X
then waits for a tape button to be pressed. If the RUN/STOP register is loaded with 8/$08 (the offset to write leader bits).
key is pressed in the meantime, the routine exits with the sta- The routine then falls through into the next one to perform
tus register carry bit set. When a button is pressed, OK is dis- the operation.
played (if messages are allowed) and the routine exits.
59942 $EA26
59890 $E9F2 Initiates tape I/O operation.
Reads next header or data block from tape. Begins by disabling all VIC-II interrupt sources and clearing
Clears the tape status flag (144/$90) and operation flag any pending VIC-II interrupts. The value in the accumulator
(147/$93) to zero; then sets the starting and ending addresses upon entry is loaded into the interrupt control register for CIA
of the cassette buffer as the starting and ending addresses for #1 (56333/$DC0D), and timer B is started. Tape operations de-
the current operation and falls through into the next routine. pend on precise timing, so all other activities that affect system
timing are disabled: RS-232 interrupts are disabled, the 40-
59899 $E9FB column screen is blanked, and the subroutine at 58740/ $E574
Reads or verifies a block from tape. is called to switch to standard (1 MHz) clock mode and disable
Calls the subroutine at 59848/$E9C8 to request that the PLAY sprites. The current address in the IIRQ vector at 788-789/
button be pressed and exits (with carry set) if the RUN/STOP $0314-$0315 is preserved in 2569-2570/$0A09-$0A0A; then
key is pressed during that subroutine. IRQ interrupts are dis- the subroutine at 61083/$EE9B is called to load a new value
abled, and a series of variables and counters are initialized. into IIRQ, according to the value in the X register. This new
The accumulator is loaded with 144/$90 (the value to enable IRQ service routine will be responsible for reading or writing
FLAG interrupts), and the X register is loaded with 14/$0E data to tape. The count of blocks to be read or written (190/
(the offset for read interrupts), and the routine branches to the $BE) is initialized to 2 (blocks are always read or written in
main tape I/O routine (59942/SEA26). pairs). The subroutine at 60762/$ED5A is called to initialize
variables; then the tape motor is started, the interlock location
59925 $EA15 (192/$C0) is set to keep it on, and a delay loop is executed to
Writes a header or data block to tape. allow the motor to get up to normal speed. IRQ interrupts are
Calls the subroutine at 59783/$E987 to set the buffer ad- then enabled to begin the reading or writing process.
dresses as the starting and ending addresses for the operation- Since the actual tape operations are performed during IRQ
then falls through into the next routine to write the buffer interrupts, the routine must now wait in a loop for the opera-
block to tape. tion to be completed. It continually tests the IRQ storage flag
(2570/S0A0A), waiting for the IIRQ vector to be reloaded with
the address stored there, which will happen after the IRQ-
driven tape routines are finished. In the meantime, the RUN/
STOP key is also tested. If that key is pressed, the operation is
542 543
.
60047 8EA8F $ED51 60753
halted and the routine exits with carry set. Otherwise, when
the original IIRQ address is restored at the end of the opera-
tion, the vector storage flag will be reset to zero, and the rou-
tine will exit with carry clear.
i Briefly, the routine reads dipoles from tape and deter-
mines whether they represent leaders, word markers, or data
bytes. The routine does not demand that the dipoles have an
absolutely exact duration, but rather it employs a concept
known as an adjustable baseline to determine whether the di-
60047 $EA8F pole is within an acceptable range for a particular type. This
Checks for RUN/STOP keypress during tape operations. makes it possible to compensate for minor variations in the
Calls the Kernal STOP routine [$FFE1] to determine whether motor speed of different Datassette units. Because two com-
the RUN/STOP key has been pressed. If it has been, the cas- plete copies of the data block are recorded, error correction is
sette motor is stopped, the default IIRQ vector address is re- possible. If an error is detected while a byte is being read from
stored, the return address of the calling routine is removed the first block, the address of the byte which could not be read
from the stack, and the IRQ vector storage flag (2570/$0A0A) is recorded in page 1. Up to 31 error addresses can be re-
is cleared. corded in 256-317/$0100-$013D. When the second block is
read, the bytes can be corrected if no error is encountered
60065 $EAA1 when the byte is read from that block.
Sets timer A to check for FLAG interrupts. When a byte is successfully read from tape, the handling
The reception of tape dipole is normally initiated by a FLAG of the byte depends on the value in the operation flag (147/
interrupt from CIA #1, which is triggered by the low-to-high $93). If the flag value is zero, the byte is stored in the location
transition on the cassette read line at the start of a dipole. pointed to by 172-173/$AC-$AD in the bank specified in
Timer A of CIA #1 is loaded with a timing value for the type 198/$C6. If the value is nonzero, the byte is compared against
of dipole being read, and it's used to check whether too much the contents of the location pointed to by 172-173/$AC-$AD
time elapses between FLAG interrupts (which should be in the bank specified in 198/$C6 (a verify operation).
equally spaced) in an attempt to determine whether any di- Errors which cannot be corrected are recorded in the tape
poles might have been missed. If no FLAG interrupt occurs status flag (144/S90). If the end of a block is reached before
before the timer counts down to zero, the timer will trigger an the specified ending address (a short-block error), bit 2 of the
interrupt. This prevents the 128 from waiting indefinitely for a flag is set to % 1 . If more than 31 errors occur while the first
FLAG interrupt. block is being read, or if an error recorded during the first
block cannot be connected during the second block, an unre-
60139 $EAEB coverable-read error occurs, and bit 4 of the flag is set to % 1 .
Reads or verifies a block of data from tape. That bit is also set during a verify operation if the byte in
{This is a tape IRQ service routine.) memory doesn't match the corresponding byte in either block
on tape. If the byte read from tape as a checksum doesn't
Reads magnetic patterns (known as dipoles) from tape, assem-
match the calculated checksum for the bytes previously read
bles them into bytes, and loads the bytes into memory (or
from tape, a checksum error occurs, and bit 5 of the flag is set
compares the bytes against memory) until a specified ending
to % 1 .
address is reached. The routine for reading from tape is the
longest and most complex one in the Kernal, and will not be
discussed in detail here. For a thorough description of the pro- 60753 $ED51
cess, refer to COMPUTERS VIC-20 and Commodore 64 Tool Kit: Loads working pointer with starting address.
Kernal, by Dan Heeb. Transfers the starting address of the current block (193-194/
$C1-$C2) to the tape working pointer (172-173/$AC-$AD).
544 545
60762 SED5A SEE57 61015
546 547
61077 $EE95 61163
$EEEB
the accumulator. If the buffer is empty, the accumulator will the X register contents will be preserved. Carry will be clear
contain 0/$00, and bit 3 of the RS-232 status flag (2580/ unless the RUN/STOP key has been pressed (the accumulator
$0A14) will be set to % 1 . For RS-232 input, the X register is will contain 0/$00) or an error is encountered when reading
unused, and the Y register value is preserved. the data block from tape (the accumulator will contain the er-
ror code).
61190 $EF06 BASIN
Accepts a byte from the current input device. 61276 SEF5C
(This routine is the normal target of the jump table entry at
65487/$FFCF, via the indirect vector at 804/$0324.) Accepts a byte from a serial device.
If the current input device (153/$99) is the keyboard (device Checks the serial status flag (144/$90) and returns the code
0), the routine sets the current cursor row and column for the RETURN character (13/$0D) if the status is nonzero
(232/$E8 and 233/$E9) as the starting row and column for in- (indicating error or end of file). Otherwise, the routine jumps
put (235/SEB and 236/$EC); then it calls the screen editor to the Kernal ACPTR routine [$E43E] to retrieve a byte from a
routine to retrieve a character from a keyboard input line serial device.
[$C009], For input from the screen (device 3), the routine
stores the device number in the input source flag (214/$D6) 61287 6EF67
and sets the current right window margin (231/$E7) as the Accepts a byte from RS-232.
ending column for input (234/$EA); then it calls the screen Calls the RS-232 GETIN routine at 61181/SEEFD to retrieve a
editor routine to retrieve a character from the screen line character from the RS-232 input buffer. If the character value
[$C009], Unfortunately, this is not the proper setup procedure is nonzero, indicating that a valid character has been returned,
for screen input, so BASIN from the screen does not work in the routine exits with that value in the accumulator. However,
the current 128 Kernal. For screen input, the ending row for because of a branch to an incorrect address, the routine ne-
input (2608/$0A30) must be specified, and the setting of bit 7 glects to clear the carry bit, which will be set as a result of the
of the input source flag must be preserved so that the screen comparison with zero. Thus, contrary to other versions of the
editor routine will know when the end of the input line is Kernal, the carry bit will be set when the character code is
reached. See the entry at 49819/$C29B for details of the valid. If the value returned is zero, the routine checks bit 6 of
proper procedure. the RS-232 status flag (2580/$0A14) to determine whether the
To retrieve a byte from a serial device (device number DSR signal is still present (indicating that the external device
greater than 3), a branch is taken to the routine at 61276/ is still active). If the flag value indicates that the DSR signal is
$EF5C. For RS-232 input (device 2), a branch is taken to the present, the routine loops back to see whether a character has
routine at 61287/$EF67. For tape (device 1), this routine falls arrived in the input buffer. If DSR is missing, the character
through into the next routine. code for RETURN, 13/$0D, is returned in the accumulator
with the carry bit clear. In any case, the X register value is un-
61224 $EF28 used and the Y register value is preserved.
Accepts a byte from tape.
Retrieves a byte from the cassette buffer (2816-3007/
61305 $EF79 BSOUT
$OBO0-$0BBF), then checks the next character in the buffer. If Sends a byte to the current output device.
that character is the zero byte marking the end of the file, bit (This routine is the normal target of the jump table entry at
6 of the tape status flag (144/S90) will be set to %1 to indicate 65490/$FFD2, via the indirect vector at 806/$0326.)
that the end has been reached. If all characters have been re- If the current output device (154/S9A) is the screen (device 3),
trieved from the buffer, the next block of data will be read. the routine jumps to the screen editor routine to display the
The retrieved byte will be in the accumulator upon exit and character in the accumulator [$C00C]. If a serial device is spec-
ified (device number greater than 3), the routine jumps to the
550 551
61332 SEF94 61430
8EFF6
CIOUT routine [$E503] to send the byte in the accumulator Checks whether the specified logical file number (184/$B8) is
over the serial bus. Otherwise, the value to be sent is stored in already used for a currently open file and exits with a Kernal
158/$9E, and the X and Y register contents are placed on the file-open error if it is (the status register carry bit will be set,
stack for later restoration. For RS-232 (device 2), a branch is and the accumulator will hold the error code, 2/$02).
taken to 61367/$EFB7. The branch will also be taken if the Next, the routine checks the number of files currently
keyboard (device 0) is specified as the output device, but that open (152/$98) and exits with a Kernal too-many-files error if
shouldn't happen if you use normal Kernal calls to set the de- ten files are already open (the carry bit will be set and the ac-
vice number—CKOUT [$F14C] won't accept the keyboard as
cumulator will hold the error code, l/$01). Otherwise, the
an output device. For tape (device 1), this routine falls through
into the following routine. number of open files is incremented and the logical file num-
ber is added to the file number table (866/$0362), The current
secondary address (185/$B9) is ORed with the value 96/S60
61332 $EF94 and placed in the corresponding position in the secondary ad-
Sends a byte to tape. dress table (886/$0376). The OR step is significant; some Kernal
Checks whether the cassette buffer has been filled. If not, the routines expect bits 5 and 6 of the secondary address to be set.
byte stored in 158/$9E is placed in the next available position The current device number (186/$BA) is placed in the cor-
in the buffer. However, if the buffer is currently full, the cur- responding position in the device number table (876/S036C).
rent block must be written before the character can be placed For files opened to the keyboard (device 0) or screen (de-
in the buffer. The subroutine to write the block to tape vice 3), the routine exits at this point, since no further setup
[$EA15] is called; then the type identifier value for a data steps are required for those devices. For RS-232 files (device
block (2/$02) is placed in the first byte of the buffer, and the 2), a branch is taken to the routine at 61504/$F040. For tape
buffer pointer (166/SA6) is initialized to the next buffer posi- (device 1), a branch is taken to the routine at 61430/$EFF6.
tion, If the RUN/STOP key is pressed while the block is being For a serial device (device number greater than 3), the subrou-
written, the routine will exit with the status register carry bit tine at 61643/$F0CB is called; then the routine exits with
set and with the accumulator containing the value 0/$00. carry clear (except in the case where the specified device is not
After the character is placed in the buffer, the X and Y present).
register values will be restored from the stack, and the accu-
mulator will be reloaded with the stored byte value so that all 61430 SEFF6
registers have the same value on exit that they did on entry. Opens a file for input or output to tape.
The carry bit will be clear upon exit. Checks the cassette buffer address and exits with a Kernal ille-
gal-device-number error if it is less than 512/$0200. The
61367 SEFB7 lower four bits of the secondary address are then tested. If all
Sends a byte to the RS-232 port. are %0, the file has been opened for reading, so the routine
Calls the routine at 59231/$E75F to store the character code searches for the specified tape header (or simply for the next
from the accumulator into the RS-232 output buffer; then header if no filename is specified). If the RUN/STOP key is
jumps into the preceding routine to restore the accumulator pressed while the routine is searching for the header, the rou-
and X and Y register values from the stack and exits with carry tine will exit with carry set and with the accumulator holding
clear. the value 0/$00. If an end-of-tape header is read before the
data header is found, the routine exits with a Kernal file-not-
61373 $EFBD OPEN found error (the carry bit will be set, and the accumulator will
Opens a logical file to a specified device. contain the error code, 4/$04), If a file header is found, the
(This routine is the normal target of the jump table entry at routine sets the buffer pointer (166/$A6) to 191/$BF {the
65472/SFFCO, via the indirect vector at 794/$031A.) value to indicate that the buffer is empty) so that the first
552 553
61504 SF040 61616
SFOBO
block of data will be read when BASIN is called for the first No error checking is done, so if you specify a value greater
time; then it exits with carry clear. than 10 (%1010) in those bits, you'll wind up with an invalid
This routine does have a flaw: It neglects to check timing constant and won't be able to send or receive data.
whether the loaded header block has a type identifier of 4 (the Also, for higher baud rates, the time between interrupts is so
type identifier for data file headers). Thus, if a program file short that the system may not have time to process received
(type identifier of 1 or 3) is found with the specified name, or bytes. In general, stick to rates of 1200 baud or lower.
before the next data header if no name is specified, it will be
The rate factor value in 2578-2579/$0A12-$0A13 is then
opened. However, tape program files cannot be read or writ-
converted into a bit timing constant, the number of CIA timer
ten, only saved or loaded, so it does no good to open them for
counts for the bit duration, and the result is stored in
reading. When a program file is opened, a long block error oc-
2582-2583/$0A16-$0A17. The formula is bit time equals rate
curs after you try to read the first block.
factor times 2 plus 200.
If any of bits 0-3 of the secondary address are % 1 , a data Next, the routine checks the handshaking setting specified
file will be opened for writing. The subroutine to request that by bit 0 of the command register. For x-line handshaking, the
the PLAY and RECORD buttons be pressed is called. If the routine checks the CIA port bit connected to the DSR line (pin
RUN/STOP key is pressed during that subroutine, the routine L of the user port). If the external RS-232 device is not holding
will exit with carry set and with the accumulator containing this line high, bit 6 of the RS-232 status flag will be set. How-
0/$00. The subroutine at 59673/$E919 is then called to write ever, there's a bug here: If the line is high, indicating that the
a data header for the file (type identifier of 4). After the external device is present, the routine will proceed with carry
header is written, the data block type identifier value (2/$02) set, which is normally used to indicate a problem. (Carry clear
is placed in the first position of the cassette buffer; then the upon return from OPEN is supposed to mean that the file has
buffer pointer is initialized to the next position, and the rou- been opened successfully.)
tine exits with carry clear.
If you're calling OPEN from machine language, you can
just remember that a set carry can be ignored when x-line
61504 $F040 handshaking is in use. However, BASIC still thinks a problem
Opens a file for RS-232 communications. has occurred and will give a DEVICE NOT PRESENT error
Calls the subroutine at 61616/$F0B0 to initialize the CIA #2 when the device is present. The converse side of the problem
port lines to the user port; then clears the RS-232 status flag is that carry will be clear when DSR is low, so BASIC will
(2580/$OA14) and retrieves up to four characters from the cur- think everything is okay when the device is absent.
rent filename (if more are specified, those after the first four The final step is to set the input buffer tail pointer
are ignored). The first character, if present, is placed in the RS- (2585/S0A19) equal to the head pointer (2584/$0A18), and
232 control register (2576/$0A10), the second into the com- the output buffer head pointer (2586/S0A1A) equal to the tail
mand register (2577/$0All), and the last two into the baud pointer (2587/$0AlB). This effectively makes both buffers ini-
rate timing constant (2578-2579/$0A12-$0A13). The number tially empty.
of bits to be sent or received is calculated and stored in
2581/$0A15. The lower four bits of the control register value
61616 $F0B0
are checked to determine the baud rate to use. If the bits are
Sets up CIA #2 ports for RS-232 communications.
all %0, a custom rate is indicated, so the following step to
load a value from the tables is skipped. Otherwise, the value Disables all interrupt sources from CIA #2; then makes the
from bits 0-3 is used as an index into one of the baud rate user port lines connected to bits 0 and 3-7 of port B inputs,
timing constant tables, depending on the video system in use while making the lines for bits 1-2 outputs and setting them
(59470/$E84E for NTSC or 59490/$E862 for PAL), and the high (+5 volts). The line for bit 2 of port A (initialized to an
specified table entry is loaded into 2578-2579/$0A12-$0A13. output line during IOINIT) is set high. This is the transmitted
data line, which is normally held high when no data is being
554 555
61643 $FOCB $F14C 61772
sent. For information on the usage of the other lines, refer to address values are loaded into 186/SBA and 185/SB9, respec-
the discussion of CIA #2 in Chapter 8. Finally, the RS-232 ac-
tively. If the device number is 0 (keyboard) or 3 (screen), the
tivity flag (2575/S0A0F) is cleared to indicate that no CIA #2
interrupts are enabled. routine skips ahead to set this as the input device number and
exit, since that's all that's necessary for input from those
sources. For device numbers greater than 3 (serial devices), a
61643 $FOCB branch is taken to the routine at 61735/$F127. For device 2
Opens a file for serial bus communications. (RS-232), a jump is taken to the routine at 59285/$E795 to
Checks the current secondary address (185/$B9) and exits im- prepare for RS-232 input. For device 1 (tape), the secondary
mediately (with the status register carry bit clear) if the sec- address is tested. If it is not 96/$60 (0/$00 before the OR in
ondary address value has bit 7 set (if the value is greater than the OPEN routine), the file has been opened for writing, so
127). The routine also exits without performing any other ac- the routine exits with a Kernal not-input-file error (the status
tions if the length of the name specified for the file being register carry bit will be set and the accumulator will hold the
opened (183/SB7) is zero. Otherwise, the serial status flag error code, 6/$06). Otherwise, the device number is set as the
(144/$90) is cleared to zero, and the specified device (186/ current input device (153/$99), and the routine exits with
$BA) is commanded to listen. If the serial status flag indicates carry clear.
that the device has not responded, the return address of the
calling routine will be discarded and the routine will exit with 61735 $F127
a Kernal device-not-present error (the carry bit will be set and
Prepares a serial device file for input.
the accumulator will contain the error code, 5/$05). If the de-
vice has responded, the secondary address is sent as a com- Sends a TALK command to the serial device specified in the
mand using the SECOND routine [$E4D2]. (The upper four accumulator, then tests the serial status flag (144/$90) to see
bits of the secondary address are masked to %0000, so only whether the device has responded. If the flag indicates that
the lower four bits are significant.) Again, if the device does the device is not present, the routine exits with a Kernal de-
not respond, the routine exits OPEN with a Kernal device-not- vice-not-present error (the status register carry bit will be set
present error. If a filename has been specified, the characters and the accumulator will contain the error code, 5/$05). If the
of the name are sent to the serial device. (Since the ATN line device has responded, the routine checks the value of the sec-
is allowed to go high after the secondary address is sent, the ondary address (185/$B9). If bit 7 of the value is %1 (if the
filename characters are not seen as commands.) The routine secondary address is 128 or greater), no secondary address is
ends by commanding the device to unlisten. sent—the routine simply performs the talk-listen turnaround.
Otherwise, the TKSA routine [$E4E0] is called to send the sec-
ondary address as a command on the serial bus and perform
61702 $F106 CHKIN the talk-listen turnaround. If the device responds again, the
Sets the current input file for GETIN and BASIN.
routine sets the device number as the current output device
(This routine is the normal target of the jump table entry at
65478/$FFC6, via the indirect vector at 798/$031E.) (154/$9A) and exits with carry clear. If the device does not re-
spond, the routine exits with a Kernal device-not-present error.
Checks whether a file with the logical file number specified in
the X register is currently open by verifying that a matching 61772 $F14C CKOUT
entry exists in the logical file table at 866-875/$0362-$036B. Sets the current output file for BSOUT.
If no match is found, the routine exits with a Kernal file-not- (This routine is the normal target of the jump table entry at
open error (the status register carry bit will be set and the ac- 65481/$FFC9, via the indirect vector at 800/$0320.)
cumulator will hold the error code, 3/$03). If an entry for the Checks whether a file with the logical file number specified in
file is found in the table, the file number is loaded into the X register is currently open by verifying that a matching
184/SB8, and the corresponding device number and secondary entry exists in the logical file table at 866-875/$0362-$036B.
556
557
61805 $F16D 61865
SF1A9
558 559
61903 SF1CF SF23D 62013
62053 $F265 LOAD the filename to the specified device; then the device is com-
Loads or verifies a program file from disk or tape. manded to talk and is sent the secondary address. The first
(This routine has a jump table entry at 65493/SFFD5.) two bytes, which, for a program (PRG) file, contain the start-
Stores the address value from the X and Y registers into the ing address, are loaded into the working pointer (174-175/
pointer to the starting address for the load (195-196/ $AE-$AF). If the original secondary address value in 158/$9E
$C3-$C4), then takes an indirect jump through the ILOAD is 0/$00, indicating that a relocating load has been specified,
vector (816/$0330). The vector normally points back to the lo- the starting address in the pointer is replaced with the one in
cation immediately following the jump, but you can modify 195-196/$C3-$C4. If Kernal messages are allowed, LOAD-
the action of the LOAD routine by redirecting this vector to a ING or VERIFYING is displayed.
routine of your own. See the ILOAD entry for details. The main reading step consists of clearing the read
The operation type value in the accumulator is stored in timeout bit (bit 1) of the serial status flag, checking for a
the load/verify flag'(147/$93), and the tape/serial status flag RUN/STOP keypress, calling ACPTR [$E43E] to read a byte
(144/$90) is cleared. The device number (186/$BA) is then from the program file, and testing whether the read timeout
tested. If it's 4 or greater, a branch is taken to the routine at bit has been set during the read. If it has been set, the routine
62075/$F27B to attempt a load from the specified serial de- loops back to try to read the byte again. If RUN/STOP is
vice. Otherwise, a jump is taken to the routine at 62246/ pressed, the routine goes to 62901/$F5B5 to halt the
$F326 to attempt a load from tape. operation.
For a verify operation (nonzero value in 147/$93), the
62075 $F27B byte read from disk is compared to the one at the address
Loads or verifies a file from a serial device. pointed to by 174-175/$AE-$AF in the bank specified in
Begins by clearing bits 6 and 0 of the fast serial flag 198/$C6. If the bytes do not match, the verify error bit (bit 4)
($2588/$0AlC). Bit 6 is cleared so that the routine which at- in the serial status flag is set to % 1 . For a load operation (0 in
tempts fast serial output will have to verify for itself that fast 147/$93), the byte read from disk is stored at the address
communications are available; there is no apparent reason for pointed to by 174-175/$AE-$AF in the bank specified in
clearing bit 0. The current secondary address (185/$B9) is 198/$C6. In either case, the address in the pointer is then in-
placed in temporary storage (158/$9E). If the length of the cremented and compared against the value 65280/$FF00. If it
current filename (183/$B7) is zero, the routine exits with the reaches this value, a Kernal out-of-memory error occurs (the
Kernal missing-filename error (the status register carry bit will routine exits with carry set and with the accumulator holding
be set and the accumulator will hold the error code, 8/$08). the error code, 16/$10). If the EOI bit in the serial status flag
Otherwise, the length value is placed in temporary storage (bit 6) is not % 1 , the routine loops back to read another byte.
(159/$9F), and (if Kernal control messages are allowed) When EOI is set, indicating that the end of the file has been
SEARCHING FOR, followed by the filename, is displayed. reached, the routine sends an UNTALK command, closes the
The subroutine at 62369/$F3Al is called to attempt a fast se- file, loads the address from 174-175/$AE-$AF (which will
rial load or verify of the specified file. If carry is clear upon re- point to the location immediately following the last byte
turn (indicating that a fast load or verify has been performed), loaded) into the X and Y registers, then exits with carry clear.
the routine exits with carry clear and with the X and Y regis-
ters holding the ending address for the data. Otherwise, the 62246 $F326
routine proceeds with the standard serial load or verify. Loads or verifies a program file from tape.
The filename length is restored from temporary storage, Exits with the Kernal illegal-device-number error if the device
and the current secondary address is set to 96/$60—cor- number in the accumulator is not 1/S01, or if the cassette
responding to a secondary address of zero, the value for read- buffer address is less than $0200. (The status register carry bit
ing a file. The serial OPEN routine [$F0CB] is called to send will be set and the accumulator will hold the error code,
562 563
62369 8F3A1 8F3EA 62442
9/$09.) Otherwise, a request for the PLAY button will be exits with the Kernal device-not-present error (tVie status regis-
printed if no buttons are currently pressed, and if Kernal mes- ter carry bit will be set and the accumulator will hold the error
sages are allowed. If the RUN/STOP key is pressed while code, 5/$05). If the command channel has been opened, the
waiting for a button press (or at any other time during the burst mode load command—UO, followed by the value 3 1 /
routine), the routine will exit with carry set and with 0/$00 in $1F to specify a program file, followed by the codes for the
the accumulator. If Kernal messages are allowed, SEARCHING characters of the filename—is sent to the drive. The CLRCH
is displayed; if a nonzero filename length is specified, that will routine [$FFCC] is called to reset the default I/O channels. Bit
be followed by FOR and the filename. If a filename is sup- 7 of the fast serial flag at 2588/$0AlC is then tested. If the se-
plied, the routine looks for a specified header block [$E99A], rial device is capable of fast serial communications, the bit will
Otherwise, it merely loads the next header block [$E8D0], In have been set to %1 by the BSOUT routine calls used to send
either case, if an end-of-tape header (type identifier of 5) is characters to the device. In this case, the routine branches to
encountered, the routine exits with a Kernal hie-not-found er- 62442/SF3EA to perform the operation using the very high
ror (the carry bit will be set and the accumulator will hold the speed burst mode. If fast serial communications are not avail-
error code, 4/$04). The routine also exits with carry set if bit 4 able, the command channel file is closed, and the routine re-
of the tape status flag (144/$90) is %1 after the header is turns with carry set, indicating that a standard (slow) load or
loaded, indicating that a read error has occurred. If the type verify must be performed.
identifier byte for the header is not 1 or 3, this is not a pro-
gram file, so the routine loops back to read another header. 62442 $F3EA
If the type identifier is 3, indicating that this is a Loads or verifies a file using fast serial burst mode.
nonrelocatable program file, or if the secondary address Performs a high-speed load or verify of the file specified in the
(185/$B9) is nonzero, the current starting address pointer preceding routine. Burst mode loads are quite different from
value in 195-196/$C3-$C4 is replaced with the one specified standard loads. In burst mode, data is sent a sector (254 bytes)
in the two header bytes following the type identifier. Next, the at a time. A status byte is sent before the data bytes for each
ending address for the file is calculated and stored in sector. The serial bus CLK line must be toggled between bytes
174-175/$AE-$AF. If the ending address value is greater than to acknowledge receipt of the byte.
65279/$FEFF, the routine exits with a Kernal out-of-memory The routine begins by restoring the filename length
error (the carry bit will be set and the accumulator will hold (183/$B7) from temporary storage (159/$9F), then disabling
the error code, 16/$10). The starting address is transferred to IRQ interrupts, allowing the serial bus CLK line to go high
a working pointer (193-194/$C1-$C2) and, if Kernal mes- and setting the serial port for fast serial input. The status byte
sages are allowed, LOADING or VERIFYING is displayed. The for the first sector is read. If the status value is 2/$02, the
subroutine at 59899/$E9FB is used to read the program data specified file has not been found, so the command channel to
from tape into the specified area of memory (carry should be the drive is closed and the routine exits with a Kernal file-not-
clear upon return if the load is successful). Finally, the ending found error (the status register carry bit will be set and the ac-
address is loaded into the X and Y registers before exiting. cumulator will hold the error code, 4/$04). If the status byte is
31/$1F, the file is only one block long. The LOADING or
62369 $F3A1 VERIFYING message is then displayed (if Kernal control mes-
Attempts to set up fast serial load or verify. sages are allowed), and the first two data bytes from the first
Checks the first character of the filename to be loaded and ex- sector are then read and stored in the starting address pointer
its immediately if it's $, indicating that a disk directory rather (174-175/$AE-$AF), If the stored secondary address (158/
than a program is to be loaded. Otherwise, the routine opens $9E) is zero, a relocating load has been specified, so the
a command file (secondary address of 15) to the specified se- pointer is reloaded with the value from 195-196/$C3-$C4.
rial device. If the file is not opened successfully, the routine The starting address is then transferred to the working pointer
(172-173/$AC-$AD).
564 565
62616 $F498 SF503 62723
Before each sector is read, the RUN/STOP key is tested. 62642 $F4B2
If that key has been pressed, a branch is taken to the routine Aborts burst mode load/verify if maximum address exceeded.
at 62630/$F4A6 to halt the operation. Otherwise, the count of Closes the file, then discards the return address of the calling
data bytes in the sector (165/$A5) is initialized—252 bytes for routine and exits with the Kernal out-of-memory error (upon
a full first sector, 254 bytes in following full sectors, and a exit, the status register carry bit will be set and the accumu-
variable number of bytes in the last sector—and the subrou- lator will hold the error code, 16/$10).
tine at 62661/$F4C5 is called to load or verify the data bytes.
After each sector is loaded or verified, the status byte for the
62650 SF4BA
next sector is read. If the status value is 0 or 1, the routine
Reads a byte using fast serial hardware.
loops to read the next sector. If it is 31/$IF, the next block is
the last one for the file, so an additional byte is read from the Waits for a serial register interrupt to occur on CIA # 1 (indi-
device. This value will be the number of bytes in the final sec- cating that a byte has been received via the fast serial hard-
tor. If the status value is 2 or greater (but not 31), an error has ware), then retrieves the byte from the serial data register and
occurred, so a branch is taken to the routine at 62616/$F498 returns it in the accumulator.
to handle the error.
62661 $F4C5
After all bytes for the file have been read, the routine al-
Loads or verifies a block of data using burst mode.
lows the CLK line to go high, reenables IRQ interrupts, and
closes the command channel file. (The status register carry bit Waits for a serial register interrupt to occur on CIA #1 (indi-
is set before CLOSE [$FFCC] is called so that the special com- cating that a byte has been received via the fast serial hard-
mand file close is performed.) The status register carry bit will ware); then retrieves the byte from the serial data register and
be clear upon exit for a successful load. Bit 4 of the serial sta- toggles the CLK line to acknowledge reception of the byte. If
tus flag (144/$90) will reflect the success of a verify operation. the operation flag (147/S93) contains a nonzero value, indicat-
ing verify, the byte read from the serial bus is compared with
62616 $F498 the one pointed to by 174-175/$AE-$AF in the bank speci-
Handles read error during burst mode load/verify. fied in 198/$C6. If the bytes do not match, the verify error bit
(bit 4) of the serial status flag (144/$90) is set to % 1 . For a
Sets bit 1 of the serial status flag (144/$90) to %1 to indicate a load operation, the byte read from the bus is stored at the ad-
read timeout. Then it discards the return address of the calling
dress pointed to by 174-175/$AE-$AF in the bank specified
routine and exits with the status register carry bit set and the
accumulator holding the value 41/$29, the code for BASIC'S in 198/$C6. The address value in the pointer is then incre-
FILE READ error message. mented; if it exceeds 65279/$FEFF, the routine will exit with
the status register carry bit set. The count of bytes to be read
from this sector (165/$A5) is decremented. If bytes remain to
62630 SF4A6 be read, the routine is repeated. Otherwise, it exits with carry
Stops burst mode load/verify if RUN/STOP key pressed.
clear and with the accumulator holding the high byte of the
Closes the file, then changes the current secondary address to next load address.
zero, discards the return address of the calling routine, and ex-
its with the status register carry bit set and the accumulator 62723 $F503
holding the value 0/$00.
Toggles state of serial bus CLK line.
Reverses the value of bit 4 of CIA #2 port A. Since the line for
this bit is connected to the serial bus CLK output line, this will
reverse the state of the line. This is the handshake for burst
mode loads from disk.
566 567
62735 $F50F 62901
SF5B5
62735 $F50F ary address is set to 97/$61, the value to open a program file
Displays SEARCHING FOR message. for writing; then a file is opened using the current filename
Checks the Kernal message flag (157/$9D), exiting immedi- (pointed to by 187-188/$BB-$BC). A LISTEN command is
ately if messages are not allowed. The message SEARCHING sent to the current device (186/$BA) along with the secondary
is displayed; then the current filename length (183/$B7) is address. The low and high bytes of the starting address for the
tested. If it's nonzero, the message FOR and the characters of save are then written as the first two bytes of the file.
the filename are displayed following SEARCHING. The subroutine at 63436/$F7CC is used to retrieve a byte
from the specified memory area, and the subroutine at 58629/
62771 $F533 $E503 is used to write the byte to the file (using fast serial
Displays LOADING or VERIFYING message. mode if it is available). After each byte, the routine checks
Loads the accumulator with the offset for either the LOAD- whether the RUN/STOP key has been pressed. If it has been
ING or VERIFYING message, depending on whether the value pressed, a branch is taken to the routine at 62901/$F5B5 to
in the operation flag (147/S93) is zero or nonzero. The routine abort the SAVE. Otherwise, the address pointer is incremented,
at 63262/$F7lE is then called to display the message (if and the process repeats until all bytes have been written.
Kernal messages are allowed). (Before this routine is called, the starting address must be
loaded into 193-194/$C1-$C2 and the ending address plus 1
62782 $F53E SAVE into 174-175/$AE-$AF.) When all bytes have been written,
Saves a block of memory to tape or disk. an UNLISTEN command is sent to the serial device; then the
routine falls through into the following one to close the file.
(This routine has a jump table entry at 65496/$FFD8.)
Stores the address value from the X and Y registers into the When fast serial communications are available, files are
pointer to the ending address for the save (174-175/$AE-$AF), loaded by sectors (254-byte chunks of data) using a special
and stores the address from the two-byte zero-page pointer feature of the 1571 drive known as burst mode. However, fast
specified in the accumulator into the pointer to the starting ad- mode SAVEs are still done byte by byte. This is the reason
dress for the save (193-194/$C1-$C2). The routine then takes more time is required to save a file using fast serial mode than
to load a file of the same length,
an indirect jump through the ISAVE vector at 818/$0332.
That vector normally points back to the location immediately
following the indirect jump, but you can modify the actions of 62878 $F59E
the SAVE routine by redirecting the vector to your own rou- Closes a file on a serial device.
tine. See the ISAVE entry in Chapter 2 for details. Exits immediately if the secondary address is greater than
The device number (186/$BA) is then tested. If it's 1 127/$7F (if bit 7 of 185/$B9 is %1). Otherwise, a LISTEN
(tape), a branch is taken to the routine at 62920/$F5C8. If it's command is sent to the current serial device; then the upper
4 or greater (serial device), a branch is taken to the routine at four bits of the secondary address are set to %1110/$E to
62817/$F561. Otherwise, the routine exits with the Kernal form the CLOSE command for the logical file. This command
illegal-device-number error (the status register carry bit will be is then sent to the current serial device, followed by an
set and the accumulator will hold the error code, 9/$09). UNLISTEN command. The routine then exits with the status
register carry bit clear. The serial status flag (144/S90) will re-
62817 SF561 flect the success of the operation.
Saves a block of memory to a serial device.
Begins by checking the filename length (183/$B7). If the 62901 $F5B5
length value is zero, the routine exits with the Kernal missing- Aborts LOAD or SAVE to serial device.
filename error (the status register carry bit will be set and the Calls the subroutine at 62878/SF59E to close the file, then
accumulator will contain the error code, 8/$08). The second- loads the accumulator with zero and exits with the status reg-
ister Z and carry bits set.
568
569
62908 $F5BC 8F65E 63070
570 571
63077 SF665 $F731 63281
1
63077 $F665 SETTIM Kernal error messages are normally disabled when BASIC
Sets the software jiffy clock. is active. (BASIC substitutes its own, more verbose error mes-
{This routine has a jump table entry at 65499/$FFDB.) sages.) However, Kernal error messages are enabled while the
Stores the value in the accumulator upon entry in 162/$A2, machine language monitor is active,
the low byte of the clock. The X register contents will be
placed in 161/$A1, the middle byte of the clock value, and 63152 $F6B0
the Y register contents will be placed in 160/$A0, the high
byte of the clock value. Table of Kernal control messages.
The messages in this table are displayed by the following rou-
63086 $F66E STOP tine. The end of each message is marked by a character with
Tests for a RUN/STOP keypress. its high bit set to % 1 .
(This routine is the normal target of the jump table entry at Offset Message
655O5/$FFE1 via the 1ST0P vector at 808/$0328.) 0/$00 I/O ERROR #
Checks the STOP key flag (145/191), set during the UDTIM 12/SOC SEARCHING
routine [$F5F8] in the IRQ sequence. If the flag contains the 23/$17 FOR
value 127/$7F, indicating that RUN/STOP has been pressed, 27/$lB PRESS PLAY ON TAPE
46/$2E PRESS RECORD & PLAY ON TAPE
the Kernal CLRCH routine [$FFCC] is called to restore default 73/$49 LOADING
I/O, and the count of characters in the keyboard buffer (208/ 81/$51 SAVING
$D0) is reset to zero. Upon exit, the status register Z bit will be 89/$59 VERIFYING
set if the RUN/STOP key has been pressed or clear otherwise. 99/$63 FOUND
106/$6A OK
63100 $F67C
Handles Kernal I/O errors. 63262 $F71E
Loads the accumulator with an error number depending on Handles Kernal control messages.
the entry point into the routine, then uses BIT opcodes to fall Begins by checking the Kernal message flag (157/$9D), exiting
through to handle the error. immediately if bit 7 of the flag is %0 (indicating that Kernal
Entry point Error number Meaning control messages are disabled). If control messages are al-
63100/$F67C 1 Too many files lowed, the value in the Y register is used as an offset to the
63103/SF67F 2 File open first character of the message in the table at 63152/$F6B0.
63106/$F682 3 File not open Characters from the message string are printed until a charac-
63109/$F685 4 File not found ter with its high bit set is encountered. Upon exit, the carry bit
63112/$F688 5 Device not present will be clear,
63115/$F68B 6 Not input file
63118/$F68E 7 Not output file 63281 SF731 SETNAM
63121/$F691 8 Missing filename Sets the length and address of filename for I/O operations.
63124/$F694 9 Illegal device number (This routine has a jump table entry at 65469/$FFBD.)
63127/$F697 16 Out of memory
Stores the value in the accumulator upon entry as the length
Next the CLRCH routine [$FFCC] is used to reset default of the current filename (183/$B7), and the value in the X and
I/O (output to screen). If Kernal error messages are allowed, Y registers as the starting address of the character codes for
I/O ERROR # is printed, followed by the character code for the the current filename (187-188/$BB-$BC). The low byte of the
digit corresponding to the error number. Upon exit, the error address should be in the X register and the high byte in Y.
number will be in the accumulator and the carry bit will be set.
572
573
63288 SF738 SF786 63366
574 575
63389 $F79D 63440
577
63450 SF7DA 63591
SF867
r
63450 $F7DA INDSTA Bank MMU Configuration Setting
Stores the accumulator contents in any bank. o/$oo 63/$3F (%00111111)
{This routine has a jump table entry at 65399/$FF77.) l/$01 127/$7F (%0111111I)
Converts the bank number for the target address, in the X reg- 2/$02 191/$BF (%10111111)
ister upon entry, into the corresponding MMU configuration 3/$03 255/$FF (%111I1111)
register setting; then calls the RAM-resident portion of the 4/$04 22/$16 (%00010110)
INDSTA routine [$02AF]. This will place the value in the ac- 5/$05 86/$56 (%01010110)
6/$06 150/$96 <%10010110)
cumulator into the specified bank at the address specified in a 214/$D6 (%11010ll0)
zero-page pointer, plus the offset in the Y register. The ad- 7/$07
8/$08 42/$2A (%00101010)
dress of the zero-page pointer must be stored in location 106/$6A (%0I101010)
697/$02B9 before this routine is called. 9/$09
10/SOA 170/$AA (%10101010)
11/$OB 234/$EA (%11101010)
63459 8F7E3 INDCMP 12/$0C 6/$06 (%00000110)
Compares the accumulator contents with a value from any bank. 13/$0D 13/$0D (%00001110)
{This routine has a jump table entry at 65402/$FF7A.) 14/$0E l/$01 (%00000001)
15/$0F 0/$00 {%00000000}
Converts the bank number for the target address, in the X reg-
ister upon entry, into the corresponding MMU configuration
register setting; then calls the RAM-resident portion of the 63488 8F800
INDCMP routine [$02BE], This will compare the value in the Code for Kernal RAM-based subroutines.
accumulator with the value at the address specified in a zero- This area of ROM contains the code for the RAM-resident por-
page pointer, plus the offset in the Y register, in the specified tions of the INDFET, INDSTA, INDCMP, JSRFAR, JMPFAR,
bank. The address of the zero-page pointer must be stored in and DMA_CALL routines. The routines are copied to the ap-
location 712/$02C8 before this routine is called. Upon return, propriate areas of RAM by the routine at 57549/SEOCD, part
the status register N, Z, and C (carry) bits will reflect the result of the reset sequence.
of the comparison.
63591 $F867 PHOENIX
63468 8F7EC GETCFG Initializes function ROMs and attempts to boot a disk in the
default drive.
Translates a bank number into an MMU register setting. (This routine has a jump table entry at 65366/$FF56.)
(This routine has a jump table entry at 65387/$FF6B.) Initializes any internal or external 128 function ROMs logged
Returns with the accumulator holding the MMU register set- during the reset sequence (by the routine at 57963/$E26B). If
ting value corresponding to the bank number in the X register a ROM is detected at one of the four possible address areas for
upon entry. See Chapter 8 for more information on the MMU. function ROMs, the corresponding byte in the ROM ID table
63472 6F7F0 at 2753-2756/$0ACl-$0AC4 will contain a nonzero value.
For logged ROMs, the JSRFAR routine is used to call the cold
Table of MMU register settings for standard banks. start vector of the ROM ($8000 or $C0O0 in bank 4, or $8000
Each of the 16 values in this table corresponds to the MMU or $C000 in bank 8). Depending on the ROMs, there may be
configuration register value that sets up one of the 16 standard no return from the JSR. However, if the routine does return
banks. from all the ROM initializations {or if no ROMs are present),
the X register is loaded with the value 8, and the accumulator
with 48/$30, the character code for 0. The routine then falls
through into the following one to attempt to boot a disk in
drive 0 of device 8.
578 579
63632 SF890 63923
63632 $F890 BOOT_CALL the name of a file to be loaded, and the drive number and a
Attempts to boot a disk. colon are placed immediately before the name in the buffer. If
(This routine has a jump table entry at 65363/SFF53.) a filename is found, the routine attempts to load a file with
Stores the value in the accumulator upon entry as the charac- that name into bank 0. Because the Kernal LOAD routine is
ter code for the current drive number and the value in the X used, this file must be PRG (program) type. This file is always
register as the current device number; then closes any open loaded into bank 0, regardless of the bank number specified
files on the specified device. The sector number ($C2/194) is for boot sectors.
initialized to 0 and the track number is initialized to 1 (booting After the file is loaded (or if no filename is specified), the
begins at sector 0 of track 1). The disk block read command is JSRFAR address pointer (3-4/$03-$04) holds the address of
copied from the table at 64008/$FA08 into the disk command the buffer location following the end-of-filename zero byte,
buffer at 256-268/$0100-$010C. Logical file 0 (the system and the JSRFAR bank (2/$02) is set for bank 15. The JSRFAR
file) is opened as a command channel and logical file 13 as a routine is then used to execute the machine language subrou-
data channel. The first boot sector is read from the specified tine following the filename in the boot sector buffer. (Some
drive into the buffer at 2816-3071/$0B00-$0BFF. If the first machine language code must be present, even if it's only an
three bytes in the sector (bytes 0-2) are the character codes for RTS opcode.) Finally, the routine exits with the status register
the letters CBM, this is a valid first boot sector. Otherwise, the carry bit clear.
drive will be reset and the routine will exit.
For a valid first boot sector, the message BOOTING is 63883 SF98B
printed; then bytes 3-4 from the sector (the load address for Resets the disk drive.
data from any following boot sectors) are stored in locations Preserves the status register and accumulator values on the
172-173/$AC-$AD, byte 5 from the sector (the bank number stack for later retrieval, then restores the data channel for
into which data is to be loaded) is stored in 174/$AE, and booting (logical file 13). The reset command (UI) is sent to the
byte 6 (the number of additional boot sectors to load) is stored disk drive; then I/O channels are reset and the command
in 175/$AF. Subsequent bytes from the sector are printed to channel (logical file 0) is closed as well. Finally, the status reg-
the screen as character codes until a byte with the value zero ister and accumulator are restored to their original values
is encountered or until the end of the sector is reached. Fol- before exiting.
lowing that message, three periods (...) will be printed.
The bank number for boot data is transferred into the 63923 $F9B3
working bank number location (198/$C6). If any more boot Loads additional boot sectors.
sectors are to be loaded (if the value in 175/$AF is nonzero), Begins by incrementing the sector number (194/SC2). If the
data from the sectors is loaded into the bank specified in count exceeds 20 (the maximum sector number for tracks
198/$C6, starting at the address in 172-173/$AC-$AD. Addi- 1-17), the sector number is reset to zero and the track number
tional sectors are loaded sequentially starting with sector 1 of (193/$C1) is incremented. (Since a maximum of 255 addi-
track 1. The high byte of the load address will not be allowed tional sectors can be loaded, all boot sectors will be located on
to roll over from 255/$FF to 0/$00, regardless of the number tracks 1-13.) The equivalent ASCII digits for the track and sec-
of boot sectors specified, (That is, the boot sectors should not tor values are then added to the block read command in the
attempt to load data to addresses above 65279/$FEFF.) buffer at 256-268/$0100-$010C, and the command is sent to
After all additional boot sectors are loaded (or if no addi- the drive via the command channel (logical file 0). The 256
tional sectors are to be loaded), the drive is reset. The routine data bytes from the sector are then read via the data channel
then searches the buffer from the zero byte marking the end (logical file 13) and are stored starting at the address in
of the message until another byte containing a zero is found. 172-173/$AC-$AD in the bank specified in 198/SC6.
The characters, if any, between the zero bytes are taken to be
580 581
63995 8F9FB SFA65 64101
63995 $F9FB Begins by clearing the status register D (decimal) bit to insure
Converts a byte value into two ASCII digits. that the system is not in decimal mode. Next, all CIA #2 inter-
Returns two character codes representing digits for the decimal rupt sources are disabled, and the interrupt control register for
equivalent of the value in the accumulator upon entry. The that chip is checked to determine whether any CIA #2 source
left digit will be in the X register upon return, and the right triggered the NMI interrupt. If so, the routine skips ahead to
digit will be in the accumulator. This routine works only for call the RS-232 handling routine. (CIA #2 interrupts are used
input values in the range 0-99/$00-$63. to drive RS-232 output.) If the NMI was not triggered by a
CIA #2 source, the routine checks whether the RUN/STOP
64008 $FA08 key is pressed. If so, it's assumed that the NMI was triggered
Table of disk commands for booting. by pressing the RESTORE key, so the RUN/STOP-RESTORE
This table holds the text for the disk block read command for sequence is performed. Otherwise, the RS-232 NMI handling
booting (Ul:13 0 01 00), the initialize command (I), and the routine [$E805] is called (if the NMI was not triggered by a
channel number command (#). CIA #2 source, this step will simply reenable any active RS-
232 CIA #2 interrupt sources), and the routine exits via the
64023 $FA17 PRIMM common interrupt return [SFF33],
Handles PRIMM (print immediate) function. The RUN/STOP-RESTORE sequence consists of the fol-
(This routine has a jump table entry at 65405/$FF7D.) lowing steps:
Begins by stashing the accumulator and X and Y register val- • A call to the RESTORE routine [$E056] to restore default
ues on the stack for later retrieval, then increments the return Kernal indirect vectors.
address on the stack and loads it into a working pointer at • A call to the IOINIT routine [$E109] to reset all I/O chip reg-
206-207/$CE-$CF. The pointer thus contains the address of isters to their default values (character definitions for 80-
the location immediately following the JSR which called this column video are normally not reinitialized).
routine. The byte at that location is retrieved and, unless its • A call to the CINT routine [$C000] to restore screen editor
value is zero, is printed as a character. The routine then loops variables to their default values (keyboard table pointers and
back to increment the address on the stack and retrieve an- programmable key definitions will normally be preserved).
other character, repeating until a zero byte is found. At that • A jump back to BASIC through the restart vector
point, the original accumulator and X and Y register values are (2560/$0A00), which normally points to the BASIC warm
restored and the routine exits. Because the return address on start entry vector, 16387/$4003.
the stack has been incremented, the routine will return to the
address following the zero byte rather than to the address fol- You can modify NMI handling by redirecting the INMI
lowing the calling JSR. vector (792-793/$0318-$0319) to a routine of your own. See
the INMI entry and Appendix A for details.
It's very important always to call this routine (or its jump
table entry) with JSR, not JMP, Only JSR puts a return address
on the stack in the expected position; entering with JMP will 64101 $FA65 IRQ
cause the stack to be garbled, which will almost certainly re- Handles IRQ interrupts.
sult in a crash. (This routine is the default target of the IIRQ indirect vector at
788/$0314.)
64064 $FA40 NMI Begins by clearing the status register D (decimal) bit to insure
that the system is not in decimal mode. The screen editor IRQ
Handles NMI interrupts.
{This routine is the default target of the INMI indirect vector at routine [SC024] is called to handle screen mode settings, scan
792/$0318.) the keyboard, and blink the cursor. If the carry is clear upon
return from that routine, indicating that the interrupt was trig-
gered by a midscreen raster interrupt, the routine exits without
583
64128 SFA80 SJTF05 65285
performing any further actions. Otherwise, the UDTIM routine This also means that these character codes cannot be re-
[$F5F8] is called to update the jiffy timers; then the tape motor turned by a key in the standard table. The special functions of
interlock handling routine [$EED0] is called. The interrupt the RUN/STOP key (halting a BASIC program, stopping a
control register for CIA #1 is read to clear any CIA #1 inter- listing, aborting a save or load, working with RESTORE, and
rupts that might have occurred. Next, the initialization status so forth) cannot be transferred to another key. That key has a
flag (2564/$0A04) is checked. If the flag has bit 0 set to % 1 , character code of 3/$03 in the standard table, but for its spe-
indicating that BASIC has been initialized, the BASIC IRQ cial functions, the keyboard column containing RUN/STOP is
routine [$4006] is called to handle sprite movement and sound scanned separately (see 63037/$F63D), and its character code
statements. Finally, the routine exits via the common interrupt is irrelevant.
return [$FF33]. Table 9-5 (the CAPS LOCK table) shows one of the more
You can modify IRQ handling by redirecting the IIRQ amusing bugs in the first version of 128 Kernal ROM. Note
vector (788-789/$0314-$0315) to a routine of your own. See the entry for the Q key. That key is separated from the other
the IIRQ entry and Appendix A for details. alphabetic keys, so the programmer at Commodore who pre-
pared this table overlooked it and neglected to change the en-
64128 $FA80 try when the other letter values were changed to their
Standard keyboard decoding tables. SHIFTed equivalents. The Q entry should be 2O9/$D1, which
The following five 89-byte tables are used to translate the explains why the Q key is unaffected by CAPS LOCK.
keyscan code generated by the SCNKEY routine [$C55D] into
the corresponding character code. The appropriate table is se- 64573-6S279 $FC3D-$FEFF Unused
lected according to the value in the shift key flag (211/$D3), All bytes in this unused area of Kernal ROM hold the value
and its address is loaded into the keyboard table pointer 255/$FF.
(204-205/$CC-$CD). Then the keyscan code is used as an
offset into the table to retrieve the appropriate character code. 65280-65284 $FF00-$FF04 MMU Registers
The table starting addresses are as follows: The MMU configuration and load configuration registers ap-
Address Table pear here in all banks (refer to Chapter 8 for details).
64128/$FA80 Standard (unshifted) and ALT
64217/$FAD9 SHIFT 65285 $FF05 JNMI
64306/$FB32 Commodore Jump to NMI handler routine.
64395/$FB8B CONTROL (This routine is the target of the processor NMI vector at
64484/$FBE4 CAPS LOCK 65530/$FFFA.)
Tables 9-1 through 9-5 show the character codes for each ta- Pushes the accumulator and X and Y register values onto the
ble. See 830-841/$033E-$0349 for information on how you stack, then places the current MMU configuration register
can customize the tables. Values in the standard table (the one value onto the stack as well. (Thus, 128 interrupts place one
addressed in 830-831/$033E-$033F, normally 64128/$FA80), more byte on the stack than do Commodore 64 interrupts.)
rather than the physical keyboard layout, determine which The routine then configures the system for bank 15 and jumps
keys are treated as shift keys. Any key having an entry in that through the INMI indirect vector at 792/$0318 to a routine to
table with one of the following values is treated as the cor- handle the NMI. The vector normally points to 64064/$FA40,
responding shift key: but you can redirect it to a routine of your own for special
l/$01 SHffT handling. See the INMI entry for details. If normal processing
2/$02 Commodore is to continue following the interrupt handling, the handling
4/$04 CONTROL routine should end with a jump to the routine at 65331/$FF33
8/$08 ALT to restore the processor registers and MMU configuration to
their original values.
584 585
r
Table 9-1. Standard (Unshifted) and ALT Decoding Table
64128-64216/$FA80-$FAD8 Table 9-2. SHIFT Decoding Table
64217-64305/$FAD9-$FB31
Table Key Character Table Key Character
index code index code Table Key Character Table Key Character
0/$00 INST/DEL 20/$14 index code index code
45/$2D 58/S3A
l/$01 RETURN 13/SOD 0/S00 INST/DEL 148/S94 45/$2D 91/55B
46/$2E @ 64/$40
2/S02 CRSR w 29/$lD 47/$2F l/$01 RETURN 141/$8D 46/$2E @ 186/5BA
44/$2C CRSR ~ 157/S9D 47/$2F 60/53C
3/$03 F7 136/$88 48/530 E 92/$5C 2/$02
4/$04 Fl 133/$85 49/$31 3/$03 F7 140/$8C 48/$30 £ 169/$A9
* 42/52A
Fl 137/$89 49/$31 * 192/$C0
5/$05 F3 134/586 50/$32 59/S3B 4/S04
6/506 F5 135/$87 5/$05 F3 138/$8A 50/$32 93/$5D
51/$33 CLR/HOME 19/$13
7/$07 CRSR I 17/$11 52/$34 6/S06 F5 139/$8B 51/$33 C L R / H O M E 147/$93
right SHIFT 1/501
8/$08 3 51/$33 53/$35 — 7/$07 CRSR 1 145/S91 52/534 right SHIFT 1/501
61/$3D
9/509 W 87/$57 54/$36 8/S08 3 35/$23 53/535 61/53D
94/$5E
10/$0A A 65/541 55/$37 9/$09 W 215/SD7 54/$36 222/$DE
/ 47/S2F A 193/$C1 55/$37
11/SOB 4 52/S34 56/$38 1 10/SOA / 63/$3F
49/S31
12/50C Z 90/$5A ll/$0B 4 36/$24 56/$38 1 33/$21
57/$39 < 95/$5F
13/$0D 83/$53 58/S3A 12/$0C Z 218/SDA 57/539 4 95/$5F
s CONTROL 4/$04
14/$0E E 69/$45 59/$3B 13/$0D s 211/SD3 58/53A CONTROL 4/$04
2 50/$32
15/$0F left SHIFT l/$01 14/$0E E 197/SC5 59/S3B 2 34/$22
60/$3C space bar 32/520
16/$10 5 53/535 61/$3D 15/$0F left SHIFT l/$01 60/$3C space bar 160/SAO
Commodore 2/S02
17/S11 82/$52 16/S10 5 37/$25 61/$3D Commodore 2/$02
R 62/$3E Q 81/$51 R 210/SD2
17/111 62/$3E Q 209/5D1
18/$12 D 68/$44 63/$3F RUN/STOP 3/$03
19/$13 6 54/S36 18/$12 D 196/SC4 63/53F RUN/STOP 131/483
64/$40 HELP 132/$84
19/$13 6 38/$26 64/540 HELP 132/$84
20/$14 C 67/$43 65/$41 8 (keypad) 56/S38
20/$14 C 195/$C3 65/541 8(keypad) 56/$38
21/$15 F 70/$46 66/$42 5(keypad) 53/$35
22/$16 84/$54 21/$15 F 198/SC6 66/$42 5 (keypad) 53/S35
T 67/$43 TAB 9/$09
23/$:7 88/$58 22/$16 T 212/SD4 67/543 TAB 24/$18
X 68/544 2 (keypad) 50/S32 23/$17 X 216/SD8 68/544 2 (keypad) 50/$32
24/$18 7 55/537 69/$45 4 (keypad) 52/$34
25/$19 Y 89/559 24/$18 7 39/$Z7 69/545 4 (keypad) 52/$34
70/$46 7 (keypad) 55/$37 Z5/S19 Y 217/$D9 70/546 7(keypad) 55/$37
26/51A G 71/$47 71/$47 1 (keypad) 49/$31 26/$1A G 199/$C7 71/$47 1 (keypad) 49/$31
27/$IB S 56/$38 72/S48 ESC 27/S1B 27/$lB 8 40/$28 72/548 ESC 27/$lB
28/$lC B 66/$42 73/$49 + (keypad) 43/S2B 28/$1C B 194/SC2 73/549 + (keypad) 43/$2B
29/$ ID l-l 72/548 74/$4A — (keypad) 45/$2D 29/$ ID H 200/$C8 74/54A - (keypad) 45/$2D
30/S1E U 85/$55 75/54B LINE FEED 10/$0A 30/$1E U 213/$D5 75/54B LINE FEED 10/$0A
31/S1F V 86/$56 76/$4C ENTER 13/$0D 31/$1F V 214/$D6 76/$4C ENTER 141/58D
32/$20 9 57/S39 77/$4D 6(keypad) 54/S36 32/$20 9 41/$29 77/$4D 6(keypad) 54/$36
33/$21 I 73/549 78/$4E 9 (keypad) 57/539 33/$21 [ 201/$C9 78/$4E 9(keypad) 57/$39
34/S22
35/523
j0 74/$4A
48/$30
79/$4F
80/$50
3 (keypad)
ALT
51/533
8/$08
34/$22
35/123
J
0
202/$CA
48/530
79/$4F 3(keypad)
ALT
51/533
8/508
36/$24 M 77/$4D 80/$50
81/$51 0(keypad) 48/$30 36/$2* M 205/$CD 81/$51 0(keypad) 48/530
37/$25 K 75/54B 82/$52 . (keypad) 46/S2E 37/$25
K 203/5CB 82/$52 . (keypad) 46/52E
38/$26 O 79/S4F 83/$53 t (cursor) 145/$91 38/$26 0 207/5CF 83/$53 T (cursor) 145/$91
39/527 N 78/S4E 84/$54 1 (cursor) 17/$11 39/$27 N 206/5CE 84/$54 1 (cursor) 17/511
40/528 + 43/52B 85/555 *- (cursor) 157/S9D 40/$28
+ 219/$DB 85/$55 - (cursor) 157/$9D
41/$29 P 80/$50 86/$56 - (cursor) 29/S1D 41/$29 P 208/5D0 86/$56 - (cursor) 29/51D
42/$2A L 76/$4C 87/$57 N O SCROLL 255/SFF 42/$2A L 204/$CC 87/$57 NO SCROLL 255/$FF
43/$2B 45/$2D 88/$58 no key 43/$2B
44/$2C - 221/$DD 88/$58 no key
46/52E pressed 255/SFF 44/$2C 62/$3E pressed 255/$FF
586
587
Table 9-3. Commodore Decoding Table Table 9-4. CONTROL Decoding Table
64306-64394/$FB32-$FB8A 64395-64483/$FB8B-$FBE3
Table Key Character Table Key Character
index code Table Key Character Table Key Character
index code cade index code
0/$00 index
1NST/DEL 148/$94 45/$2D 91/$5B 0/500 INST/DEL 255/5FF 45/$2D 27/51B
1/S01
2/502
RETURN
CRSR —
141/SSD
157/$9D
46/S2E
47/52F
@ 164/SA4
60/$3C
l/$01
2/502
RETURN
CRSR —
255/$FF
255/SFF
46/$2E
47/S2F
b 0/$00
255/$FF
3/$03 F7 U0/$8C 48/$30 E 168/5A8 3/503 F7 255/$FF 48/S30 £ 28/$lC
4/$04 Fl 137/$89 49/$31 223/$DF 4/$04 Fl 255/$FF 49/$31 255/$FF
5/$05 F3 138/$8A 50/$32 93/55D 5/$05 F3 255/$FF 50/$32 ; 29/$lD
6/$06 F5 139/$8B 51/$33 CLR/HOME 147/S93 6/$06 F5 255/SFF 51/S33 C L R / H O M E 255/$FF
7/$07 CRSR I 145/$91 52/534 right SHIFT l/$01 7/S07 255/$FF 52/S34
8/$08 3 150/596 53/$35 =
CRSR I right SHIFT 255/$FF
61/S3D 3 28/51C 53/$35 = 31/51F
9/$09 W 179/$B3 54/$36 * 222/5DE 9/$09 W 23/517 54/$36 30/51E
10/50A A 176/$B0 55/$37 / 63/53F 10/$0A A l/$01 55/537 / 255/$FF
11/50B 4 151/S97 56/$38 1 129/$81 ll/$0B 4 159/$9f 56/$38 1 144/S90
12/50C Z 173/$AD 57/539 4 95/$5F 12/$0C Z 26/51A 57/$39 4 6/$06
13/SOD 174/$AE 58/$3A
14/$0E
s
E 177/5B1 59/$3B
CONTROL
2
4/$04 13/$0D S 19/513 58/$3A CONTROL 255/$FF
149/595 14/$0E E 5/$05 59/S3B 2 5/505
15/$0F left SHIFT 1/S01 60/$3C space bar 160/$A0 15/$0F left SHIFT 255/$FF 60/$3C space bar 255/$FF
16/$10 5 152/$98 61/S3D Commodore 2/$02 16/S10 5 156/$9C 61/$3D Commodore 255/$FF
17/511 R 178/$B2 62/53E Q I71/5AB 17/$11 R 18/512 62/$3E Q 17/$11
18/$12 D 172/$AC 63/$3F RUN/STOP 3/$03 1S/S12 D 4/$04 63/53F S U N / S T O P 255/$FF
19/$13 6 153/$99 64/$40 HELP 132/584 19/$13 6 30/S1E 64/$40 HELP 132/$84
20/$14 C 188/$BC 65/$41 8(keypad) 56/538 20/$14 C 3/$03 65/$41 8(keypad) 56/$38
21/515 F 187/$BB 66/542 5 (keypad) 53/$35 21/S15 F 6/$06 66/$42 5 (keypad) 53/535
22/516 T 163/$A3 67/543 TAB 24/$18 22/$16 T 20/514 67/$43 TAB 24/$18
23/$17 X 189/5BD 68/$44 2 (keypad) 50/S32 23/$17 X 24/518 68/$44 2(keypad) 50/532
24/$18 7 154/$9A 69/$45 4 (keypad) 52/534 24/$18 7 31/51F 69/$45 4 (keypad) 52/534
25/$19 Y 183/5B7 70/S46 7 (keypad) 55/537 25/$19 Y 25/519 70/$46 7(keypad) 55/$37
26/51A G 165/SA5 71/$47 1 (keypad) 49/$31 26/$1A G 7/$07 71/$47 1(keypad) 49/$31
27/51B 8 155/59B 72/548 ESC 27/$IB 27/$lB 158/$9E
8 72/$48 ESC 27/51B
28/51C B 191/SBF 73/$49 + (keypad) 43/$2B 28/$lC B 2/S02 73/$49 + (keypad) 43/52B
29/$ ID H 180/$B4 74/$4A - (keypad) 45/$2D 29/$ ID H 8/$08 74/54A - (keypad) 45/52D
30/$IE U 184/$B8 75/S4B LINE FEED 10/$0A 30/$IE 21/$15 75/$4B LINE FEED
31/$1F 190/$BE
U 10/50A
V 76/S4C ENTER 141/58D 31/51F V 22/516 76/$4C ENTER 141/$8D
32/$20 9 41/529 77/54D 6 (keypad) 54/J36 32/$20 9 18/512 77/$4D 6(keypad) 54/$36
33/$21 I 162/$A2 78/$4E 9 (keypad) 57/539 33/$21 1 9/$09 78/$4E 9(keypad) 57/$39
34/$22 I 181/$B5 79/$4F 3(keypad) 51/533 34/$22 10/50A 79/$4F 3(keypad) 51/533
35/$23 0 48/$30 80/S50 ALT 8/508 35/S23 r0 146/$92 80/550 ALT 8/$08
36/$24 M 167/$A7 81/$51 0(keypad) 48/530 36/$24 M 13/50D 81/S51 0(keypad) 48/530
37/$25 K 161/$A1 82/$52 .(keypad) 46/$2E 37/525 K 82/$52 .(keypad) 46/$2E
ll/$0B
3S/$26 0 185/$B9 83/$53 T (cursor) 145/591 38/526 O 15/50F 83/S53 f (cursor) 145/$91
39/$27 N 170/$AA 84/$54 •I (cursor) 17/$11 39/527
N 14/SOE 84/$54 i (cursor) 17/$11
40/$28 + 166/$A6 85/S55 * (cursor) 157/$9D 40/$28
+ 255/$FF 85/S55 - (cursor) 157/$9D
41/S29 P 175/SAF 86/$56 - (cursor) 29/$ ID 41/529
P 16/$10 86/$56 •• (cursor) 29/51D
42/$2A L 182/5B6 87/$57 N O SCROLL 255/$FF 42/52A
43/$2B 43/S2B L 12/SOC 87/$57 N O SCROLL 255/$FF
- 220/5DC 88/558 no key 255/5FF
44/S2C 62/$3E 44/S2C - 88/$58 no key
pressed 255/5FF 255/5FF pressed 255/$FF
588 589
SFFiZ. 65303
Table 9-5. CAPS LOCK Decoding Table This routine is also copied into all RAM banks to handle
64484-64572/$FBE4-$FC3C interrupts which occur when the system is configured for a
Table Key Character Table Key Character bank where Kernal ROM is not visible.
index code index code
0/$00 INST/DEL 20/$14 45/$ 2D : 58/S3A
l/$01 RETURN 13/$0D 46/S2E
65303 $FF17 JIRQ
@ 64/$40
2/E02 CRSR <- 29/$ ID 47/$2F 44/$2C Jump to IRQ or BRK handler routine.
3/$03 F7 136/$88 48/$30 £ 92/$5C (This routine is the target of the processor IRQ/BRK vector at
4/$04 Fl 133/$85 49/$31 • 42/$2A 65534/$FFFE.)
5/$05 F3 134/S86 50/$32 59/$3B Pushes the accumulator and X and Y register values onto the
6/$06 F5 135/$87 51/$33 CLR/HOME 19/313
7/S07 CRSR ! 17/S11 52/$34 right SHIFT l/$01
stack, then places the current MMU configuration register
8/$O8 3 51/$33 53/$35 — 61/$3D
value onto the stack as well. (Thus, 128 interrupts place one
9/$09 W 215/$D7 54/$36 * 94/S5E more byte on the stack than do Commodore 64 interrupts.)
10/$0A A 193/SCI 55/$37 / 47/$2F The routine then configures the system for bank 15 and reads
11/$OB 4 52/$34 56/$38 1 49/$31 the processor status register value on the stack (the interrupt
12/SOC Z 218/SDA 57/$39 4 95/$5F
automatically causes the status register value and return ad-
13/SOD s 211/$D3 58/$3A CONTROL 4/$04
H/$0E E 197/$C5 59/$3B 2 50/$32 dress to be placed on the stack before this routine is called). If
15/SOF left SHIFT l/$01 60/$3C space bar 32/S20 the B bit (bit 4) of the status register is set to % 1 , indicating
16/$10 5 53/135 61/$3D Commodore 2/$02 that the interrupt is the result of the execution of a BRK in-
17/$11 R 210/SD2 62/$3F_ Q 81/$51 struction (a software interrupt), the routine jumps through the
1S/S12 D 196/$C4 63/$3F RUN/STOP 3/$03 IBRK indirect vector at 790/$0316 to a routine to handle the
19/$13 6 54/$36 64/$40 HELP 132/$84
BRK. That vector normally points to 45059/$B003, the break
20/$14 C 195/$C3 65/$41 8 (keypad) 56/$3S
21/$15 F 198/$C6 66/$42 5 (keypad) 53/$35 entry point into the machine language monitor. If the B status
22/$16 T 212/$D4 67/$43 TAB 9/$09 bit is %0, a hardware interrupt has been triggered by an exter-
23/$17 X 216/$D8 6S/$44 2 (keypad) 50/S32 nal source, so the routine jumps through the IIRQ indirect vec-
24/$18 7 55/$37 69/$45 4 (keypad) 52/$34 tor at 788/$0314. That vector normally points to the handling
25/$19 Y 217/$D9 70/$46 55/$37
7 (keypad) routine at 64101/$FA65. In either case, you can redirect the
26/$lA G 199/SC7 71/$47 1(keypad) 49/$31
vector to a routine of your own for special handling. See the
27/$lB 56/$38 72/$48 ESC 27/$IB
28/$lC
eB 194/$C2 73/$49 + (keypad) 43/$2B IBRK and IIRQ entries for details.
29/$lD H 200/$C8 74/$4A - (keypad) 45/$2D If normal processing is to continue following the interrupt
3O/$1E U 213/$D5 75/$4B LINEFEED 10/$0A handling, the handling routine should end with a jump to the
31/$1F V 2U/SD6 76/$4C ENTER 13/$0D
routine at 65331/$FF33 to restore the processor registers and
32/$20 9 57/S39 77/$4D 6(keypad) 54/$36
33/S21 I 201/SC9 78/S4E 9(keypad) 57/$39
MMU configuration to their original values. For example, the
34/$22 J 202/SCA 79/$4F 3(keypad) 51/$33 normal IRQ service routine exits in this manner, so processing
35/$23 0 48/S30 80/$50 ALT 8/$08 resumes unaffected after a standard IRQ interrupt. However,
36/$24 M 205 /$CD 81/S51 0(keypad) 48/$30 the BRK service routine does not return, since normal process-
37/$25 K 203/$CB 82/$52 . (keypad) 46/$2E ing is halted when the monitor is entered.
38/$26 O 207/$CF 83/$53 ! (cursor) 145/$91
39/$27 N 206/$CE 84/S54 I (cursor) 17/$11 This routine is also copied into all RAM banks to handle
40/$28 + 43/$2B 85/$55 *• (cursor) 157/$9D interrupts which occur when the system is configured for a
41/$29 P 208/SDO 86/$56 -• (cursor) 29/$lD bank where Kernal ROM is not visible.
42/$2A L 204/$CC 87/$57 NO SCROLL 255/$FF
43/$2B - 45/S2D 88/$58 no key
44/$2C 46/S2E pressed 255/SFF
590 591
65331 SFF33 $FF53 65363
65331 8FF33 CRTI device. (This is different from the Kernal CLALL routine
Common exit routine for all interrupt routines. f$FFE71, which merely resets the number of open files to zero
Retrieves the MMU configuration register value from the stack without explicitly closing any open files.) Enter the routine
and restores the system to its original bank setting, then re- with the accumulator holding the number of the device on
stores the Y and X register and accumulator values from the which files are to be closed. If the specified device is the cur-
stack. Processing resumes at the instruction following the one rent input or output device, the channel will be reset to the
during which the interrupt has occurred. default device {screen or keyboard). If all files to the device
have been successfully closed, the status register carry bit will
65341 $FF3D JRESET clear upon return. A set carry bit indicates that a device error
Jump to reset handler routine. has occurred.
(This routine is the target of the processor RESET vector at
65532/$FFFC.) 65357 $FF4D JC64_MODE
Sets the system for the bank 15 configuration, then jumps to Entry point for the Kernal C64_MODE routine at 57931/
the RESET routine [$E000]. $E24B, which switches the system immediately to 64 mode.
This routine is also copied into all RAM banks to handle To get back to 128 mode, it is necessary to reset the computer
any reset which might occur when the system is configured or to turn it off and back on.
for a bank where Kernal ROM is not visible.
65360 $FF50 JDMA_CALL
65349-65350 $FF45-$FF46 Unused Entry point for the Kernal DMA_CALL routine at 63397/
Two unused bytes, filled with the value 255/SFF. $F7A5, which passes commands to a DMA (direct memory
access) controller. The DMA device will take control of the
system to perform the requested command. The only DMA
New 128 Kernal Jump Table peripherals currently available for the 128 are the 1700 and
Locations 65351-65407/$FF47-$FF7F are a table of jump vec- 1750 Memory Expansion Modules, controlled by a DMA chip
tors to routines found in 128 ROM, but not in previous ver- known as the REC (see Chapter 8 for more information). Call
sions of the Kernal for earlier Commodore computers. As with the routine with the Y register holding the command for the
the other jump tables, each table entry consists of a JMP DMA device and the X register holding the bank number for
opcode (76/$4C) followed by the address of the target routine. the operation. Additional setup steps may be required, de-
pending on the command.
65351 SFF47 JSPIN_SPOUT
Entry point for the Kernal SPIN-SPOUT routine at 58875/ 65363 SFF53 JBOOT_CALL
$E5FB, which sets up the serial bus for fast communications Entry point for the Kernal BOOT_CALL routine at
mode. Enter with the status register carry bit clear to establish 63632/$F890, which attempts to load and execute boot sectors
fast serial input or with the bit set to establish fast serial out- from a specified disk drive. Call the routine with the X register
put. Unless you are writing a custom data transfer routine, it's holding the device number for the desired disk drive (usually
not necessary to call this routine explicitly. All the standard 8) and the accumulator holding the character code correspond-
serial I/O routines already include this setup step. ing to the desired drive number—not the actual drive number.
(For example, the single drive in 1541 and 1571 units is desig-
65354 $FF4A JCLOSE^ALL nated drive 0, so you would use 48/$30, the character code
Entry point for the Kernal CLOSE_ALL routine at 62013/ for zero.) If the specified drive is not present or turned off, or
$F23D, which closes all files currently opened to a specified tf the disk in the drive does not contain valid boot sectors, the
592 593
65366 SFF56 65381
SFF65
routine will return with the status register carry bit set. If boot
sectors are found and executed, the boot code may or may not the X register the device number. However, if the secondary
return to the calling routine. address is not currently used, the carry bit will instead be set
upon return (the secondary address value will still be in the Y
65366 8FF56 JPHOENIX register).
Entry point for the Kernal PHOENIX routine at 63591/$F867, 65375 $FF5F JSWAPPER
which initializes any installed-function ROMs and attempts to
boot a disk from the default drive (drive 0 of device 8). The Calls the Kernal SWAPPER routine's screen editor jump table
Kernal reset routine [$E000] records the presence of function entry at 49194/$C02A. The routine switches active screen dis-
ROMs in cartridges plugged into the expansion port or into plays by exchanging the active and inactive screen editor vari-
the spare ROM socket on the system circuit board, but it does able tables, tab stop bitmaps, and line link bitmaps, and by
not initialize them unless they are autostarting (unless their toggling bit 7 of the active screen flag (215/$D7). The routine
cartridge ID byte holds the value 1). This routine initializes all doesn't physically turn either video chip on or off; both chips
recorded function ROMs by calling their cold start entry ad- remain enabled. Instead, the routine determines which display
dresses (the first address of the memory slot for the ROM). If will be the recipient of subsequent printing. (Only the active
any ROMs are present, they may or may not return to this screen will have a "live" cursor.)
routine, depending on the initialization steps performed. If all
ROMs return after initialization (or if no ROMs are present), 65378 $FF62 JDLCHR
the routine attempts to boot a disk in drive 0 of device 8. Calls the Kernal INIT80 routine's screen editor jump table en-
try at 49191/$C027. The routine copies character shape data
65369 $FF59 JLKUPLA from ROM into the 8563 80-column video chip's private
block of RAM (the 8563 has no character ROM of its own).
Entry point for the Kernal LKUPLA routine at 63389/$F79D,
which checks whether a specified logical file number is cur- 65381 $FF65
rently in use. Call the routine with the accumulator holding JPFKEY
the desired logical file number. If that number is used for a Calls the Kernal KEYSET routine's screen editor jump table
currently open file, the status register carry bit will be clear entry at 49185/$C021. The routine assigns a new definition to
upon return. The accumulator will still hold the logical file one of the ten programmable function keys (F1-F8, SHIFT-
number; the X register will hold the associated device number, RUN/STOP, and HELP). Call the routine with the accumu-
and the Y register the secondary address. However, if the logi- lator holding the address of a three-byte string descriptor in
cal file number is not currently used, the carry bit will instead zero page, the X register containing the key number (1-10),
be set upon return (the logical file number will still be in the and the Y register containing the length of the new definition
accumulator). string. The descriptor in zero page should consist of the two-
byte address of the new definition string (in standard low-
65372 $FF5C JLKUPSA byte/high-byte order), followed by the bank number where
the definition string is located. The key number is not checked
Entry point for the Kernal LKUPSA routine 63366/$F786, for validity; if you specify a value outside the acceptable
which checks whether a specified secondary address is cur- range, you may garble existing definitions. Upon return, the
rently in use. Call the routine with the Y register holding the carry bit will be clear if the new definition has been success-
desired secondary address. If that number is used for a cur- fully added, or it will be set if there is insufficient room in the
rently open file, the status register carry bit will be clear upon definition table for the new definition.
return. The Y register will still hold the secondary address; the
accumulator will hold the associated logical file number, and
594
595
65384 $FF68 SFF74. 65396
65384 $FF68 JSETBNK value, and 9/$ 09 will hold the stack pointer value. The sys-
Entry point for the Kernal JSETBNK routine at 63295/$F73F, tem is always reconfigured for bank 15 upon exit.
which establishes the current bank from which data will be
read or to which data will be written during load/save opera- 65393 $FF71 JJMPFAR
tions, as well as the bank where the filename for the I/O op- Entry point for the Kernal JMPFAR routine at 739/S02E3,
erations can be found. Call the routine with the accumulator which jumps to a routine in a specified bank, with no return
holding the bank number for data and the X register holding to the calling bank. Prior to calling this routine, you must load
the bank for the filename. All register values are preserved location 2/$02 with the bank number (0-15) of the target rou-
during this routine. tine and locations 3-4/$03-$04 with the address of the target
routine (in high-byte/low-byte order, the opposite of the nor-
65387 $FF6B JGETCFG mal arrangement). You should also load location 5/$05 with
Entry point for the Kernal GETCFG routine at 63468/$F7EC, the value you want placed in the status register when the tar-
which translates a bank number into the MMU register setting get routine is entered. (The behavior of many routines is influ-
which will configure the system for that bank. Call the routine enced by the status register setting, particularly the state of the
with the X register containing the bank number (0-15). Upon carry bit. Load 5/$05 with the value 0/$00 if the target rou-
return, the accumulator will hold the corresponding MMU tine is to be entered with carry clear or with l/$01 if it is to
configuration register setting value. The routine does not check be entered with carry set.) If you wish to pass other register
the validity of the bank number input. If you specify a number values to the routine you will be calling, store the desired ac-
outside the acceptable range, the routine will return a mean- cumulator value in location 6/$06, the X register value in
ingless value. 7/$07, and the Y register value in 8/$08.
596 597
65399 $FF77 $fF84 65412
65399 $FF77 JINDSTA changing the address in the zero-page pointer by simply incre-
Entry point for the Kernal INDSTA calling routine at 63450/ menting the Y register between calls.
$F7DA, which stores the accumulator contents at an address
in a specified bank. Prior to calling this routine, you must load 65405 $FF7D JPRIMM
a two-byte zero-page pointer with the address of the location Entry point for the Kernal PRIMM routine 64023/$FA17,
at which the byte is to be stored (or the base location if a se- which prints the string of character codes immediately follow-
ries of bytes is to be stored); then store the address of this ing the JSR to this routine. You must always call this routine
pointer in location 697/$02B9. Call the routine with the accu- with JSR, never with JMP. Only JSR places the required ad-
mulator holding the byte to be stored, the X register holding dress information on the stack. The end of the character code
the bank number (0-15) for the target location, and the Y reg- string is indicated by a byte containing 0/$00 (the routine
ister holding an offset value which will be added to the ad- continues printing bytes as character codes until a zero byte is
dress in the pointer to determine the location in which the encountered). When the ending marker is found, the routine
byte is to be stored. (Load Y with zero if no offset is desired.) returns to the address immediately following the zero byte.
Upon return, the accumulator will still hold the byte value.
The value in the Y register will also be preserved. If you are 65408 $FF80
writing data to a series of locations, it is necessary to reload
the X register with the bank number before every call to this Some Commodore literature suggests that this location will be
routine, but you can write to up to 256 sequential locations updated in future revisions of the Kernal ROM to indicate the
without changing the address in the zero-page pointer by sim- revision number. For the original version of the 128 Kernal,
ply incrementing the Y register between calls. this location contains the value 0/$00.
65415 SFF87 JRAMTAS Cl44/$90) upon return will indicate whether the operation is
Entry point for the Kernal RAMTAS routine at 57491/$E093, successful.
which clears zero-page RAM (locations 2-255/$02-$FF) and
initializes Kernal memory pointers. The routine also sets the 65433 $FF99 JMEMTOP
BASIC restart vector (2560/$0A00) to point to BASIC'S cold Entry point for the Kernal MEMTOP routine at 63331/$F763,
start entry address, 16384/$4000. which reads or sets the value of the Kernal's top-of-memory
pointer (2567-2568/$0A07-$0AO8). To read the pointer, call
65418 SFF8A JRESTOR the routine with the carry flag set; the pointer value will be re-
Entry point for the Kernal RESTOR routine at 57430/$E056, turned in the X and Y registers (low byte in X, high byte in Y).
which restores the Kernal indirect vectors at 788-819/ To set the pointer, call the routine with the carry flag clear
$0314-$0333 to their default values. and with the X and Y registers containing the low and high
bytes, respectively, of the desired pointer value.
65421 $FF8D JVECTOR
Entry point for the Kernal VECTOR routine at 57435/SE05B, 65436 $FF9C JMEMBOT
which loads or stores the Kernal indirect vectors at 788-819/ Entry point for the Kernal MEMBOT routine at 63346/$F772,
$0314-$0333. When this routine is called, the X and Y regis- which reads or sets the value of the Kernal's bottom-of-memory
ters should be loaded with the address of a 32-byte table (low pointer (2565-2566/$0A05-$0A06). To read the pointer, call
byte in X, high byte in Y). If the status register carry bit is the routine with the carry flag set; the pointer value will be re-
clear when the routine is called, the vectors will be loaded turned in the X and Y registers (low byte in X, high byte in Y).
with the values from the table. If carry is set, the 16 two-byte To set the pointer, call the routine with the carry flag clear
address values currently in the vectors will be copied to the and with the X and Y registers containing the low and high
table. bytes, respectively, of the desired pointer value.
the length of the filename and the X and Y registers holding direct vector (796/$031C), which normally points to the
the address of the first character of the name (low byte in X, CLOSE routine at 61832/$F188. You can modify the actions
high byte in Y). The Kernal SETBNK routine [$FF68] must be of the routine by changing the vector to point to a routine of
used to specify the appropriate bank for the filename address. your own. See the ICLOSE entry for details.
If no name is used for the current operation, load the accumu- The standard CLOSE routine should be called with the
lator with the value 0/$00; the values in X and Y are then ir- accumulator holding the number of the logical file to be
relevant. All register values are preserved during this routine. closed. If no file with the specified logical file number is cur-
rently open, the routine exits immediately. (No error will be
65472 $FFCO JOPEN indicated.) If a file with the specified number is open, its entry
Entry point for the Kernal OPEN routine, which opens a logi- in the logical file number, device number, and secondary ad-
cal file to a specified device. The routine is entered via the dress tables will be removed. For RS-232 files, the driving CIA
IOPEN indirect vector (794/$031A), which normally points to #2 interrupts will be disabled. For tape files, the final block of
the OPEN routine at 61403/$EFDB. You can modify the ac- data will be written (followed by an end-of-tape marker, if one
tions of the routine by changing the vector to point to a rou- has been specified). For disk files, the EOI sequence will be
tine of your own. See the IOPEN entry for details. performed. However, the 128 Kernal routine offers a special
At least one preparatory step is required before the stan- close function for disk files: If this routine is called with the
dard OPEN routine is called: The SETLFS routine [$FFBA] status register carry bit set, and if the device number for the
must be called to establish the logical file number (184/$B8), file is 8 or greater, and if the file has been opened with a sec-
the device number (186/SBA), and the secondary address ondary address of 15, the EOI sequence is skipped (the table
(185/$B9). For tape (device 1), RS-232 (device 2), or serial (de- entries for the file are deleted, but that's all). This provides a
vice 4 or higher), SETBNK [$FF68] and SETNAM [$FFBD] are solution to a problem in earlier versions of the Kernal. A disk
also required to specify the length (183/$B7) and address file opened with a secondary address of 15 is a command
(187-188/$BB-$BC) of the associated filename and the bank channel to the drive. Performing an EOI sequence to such a
number (199/$C7) where the filename can be found. file closes all files currently open to the drive, not just the
The status register carry bit will be clear if the file is suc- command channel file. This special mode allows the command
cessfully opened, or set if it cannot be opened. When carry is channel file to be closed without disturbing other files that
set upon return, the accumulator will hold an error code indi- may be open to the drive.
cating the problem. Possible error code values include 1 (10
files, the maximum allowed, are already open), 2 (a currently 65478 $FFC6 JCHKIN
open file already uses the specified device number), and 5 Entry point for the Kernal CHKIN routine, which specifies a
(specified device did not respond). One exception is when RS- logical file as the source of BASIN and GETIN input. The rou-
232 files are opened with x-line handshaking. Because of a tine is entered via the ICHKIN indirect vector (798/$031E),
bug in the RS-232 OPEN routine [$F040], carry will be set if which normally points to the CHKIN routine at 61702/$F106.
the RS-232 device is present when x-line handshaking is used You can modify the actions of the routine by changing the
(if the DSR line is high), or it will be clear if the device is ab- vector to point to a routine of your own. See the ICHKIN en-
sent—the opposite of the proper setting. The RS-232 and try for details.
tape/serial status flags (2580/$OA14 and 144/$90, respec- For a logical file to receive input, it must first be opened
tively) also reflect the success of the operation. (see the OPEN routine entry at 65472/$FFC0). The standard
CHKIN routine should be called with the desired logical file
65475 $FFC3 JCLOSE number in the X register. The input channel (153/$99) is set
Entry point for the Kernal CLOSE routine, which closes a to the device number for that file. If the device is RS-232 (de-
specified logical file. The routine is entered via the ICLOSE in- vice number 2), the routine also enables the CIA #2 interrupts
604 605
65481 SFFC9 65487
SFFCF
responsible for RS-232 reception. If a serial device (device actions of the routine by changing the vector to point to a rou-
number 4 or greater) has been specified, the device is also made tine of your own. See the ICLRCH entry for details.
a talker on the serial bus. If the file has successfully been set The standard CLRCH routine resets the output channel
for input, the carry bit will be clear upon return. If carry is set, (154/$9A) to device 3, the video display. (If the previous out-
the operation is unsuccessful and the accumulator will contain put channel is a serial device, it will be sent an UNLISTEN
the Kernal error code indicating which error has occurred. Pos- command.) The input channel (153/$99) is reset to device 0,
sible error codes include 3 (file not open), 5 (device did not re- the keyboard. (If the previous input channel is a serial device,
spond), and 6 (file not open for input). The RS-232 and serial it will be sent an UNTALK command.)
status flags (2580/$0A14 and 144/$90, respectively) also re-
flect the success of the operation on one of those devices. 65487 $FFCF JBASIN
Entry point for the Kernal BASIN routine (called CHRIN in
65481 SFFC9 JCKOUT previous versions of the Kernal), which receives a byte from
Entry point for the Kernal CKOUT routine, which specifies a the logical file currently specified for input. The routine is en-
logical file as the recipient of BSOUT output. The routine is tered via the IBASIN indirect vector (804/$0324), which nor-
entered via the ICKOUT indirect vector (800/$0320), which mally points to the BASIN routine at 61190/$EF06. You can
normally points to the CKOUT routine at 61772/$F14C. You modify the actions of the routine by changing the vector to
can modify the actions of the routine by changing the vector point to a routine of your own. See the IBASIN entry for
to point to a routine of your own. See the ICKOUT entry for details.
details. Except to retrieve input from the keyboard when the sys-
For output to be sent to a logical file, it must first be tem is set for default I/O, you must open a logical file to the
opened (see the OPEN routine entry at 65472/$KFC0). The desired device and specify the file as the input source (see the
standard CKOUT routine should be called with the desired entries for the OPEN and CHKIN routines, 65472/$FFC0 and
logical file number in the X register. The output channel 65478/$FFC6, respectively). For keyboard input (device 0), the
(154/$9A) is set to the device number for that file. If the de- standard BASIN routine accepts keypresses until RETURN is
vice is RS-232 (device number 2), the routine also enables the pressed; then it returns characters from the input string one at
CIA #2 interrupts responsible for RS-232 transmission. If a se- a time on each subsequent call. The character code for RE-
rial device (device number 4 or greater) has been specified, the TURN, 13/$0D, is returned when the end of an input string is
device is also made a listener on the serial bus. If the file has reached. (Generally, the GETIN routine [$FFE$] is preferred
successfully been set for output, the carry bit will be clear for retrieving individual keypresses.) BASIN from tape (device
upon return. If carry is set, the operation is unsuccessful and 1) retrieves the next character from the cassette buffer. If all
the accumulator will contain the Kernal error code indicating characters have been read from the buffer, the next data block
which error has occurred. Possible error codes include 3 (file is read from tape into the buffer. BASIN from RS-232 (device
not open), 5 (device did not respond), and 7 (file not open for 2) returns the next available character from the RS-232 input
output). The RS-232 and serial status flags (2580/$0A14 and buffer. If the buffer is empty, the routine waits until a charac-
144/$90, respectively) also reflect the success of the operation ter is received—unless the RS-232 status flag (2580/$0A14)
on one of those devices. indicates that the DSR signal from the external device is miss-
ing, in which case a RETURN character code, 13/$0D, is
65484 $FFCC JCLRCH returned.
Entry point for the Kernal CLRCH routine, which resets the BASIN from the screen (device 3) is supposed to retrieve
system for default I/O sources. The routine is entered via the characters one at a time from the current screen line, ending
ICLRCH indirect vector (802/$0322), which normally points with a RETURN character code when the last nonspace char-
to the CLRCH routine at 61990/$F226. You can modify the acter on the logical line is reached. However, it does not work
606 607
65490 SFFD2 $FFD5 65493
properly in the current version of the 128 Kernal (see the en- full, the routine waits until a character is sent. BSOUT to the
try for 49819/SC29B in Chapter 7 for details). BASIN from se- screen (device 3) [$C00C] prints the character on the active
rial devices (device numbers 4 and higher) returns the next display at the current cursor position. The CIOUT routine
character available from the serial bus, unless the serial status r$FFA8] is used for output to serial devices (device numbers 4
flag (144/S90) contains a nonzero value. In that case, the RE- and higher).
TURN character code is returned. Regardless of the output device, the contents of the accu-
For all input devices, the received byte will be in the ac- mulator and X and Y registers will be preserved during this
cumulator upon return. The contents of the X and Y registers routine. The status register carry bit will always be clear upon
will be preserved during input from keyboard, screen, or RS- return unless tape output has been aborted by pressing the
232. For input from tape, only the X register contents are pre- RUN/STOP key (in that case, the accumulator will also be set
served. For input from serial devices, only the Y register to 0/$00 to set the Z bit as well). For tape, serial, or RS-232
contents are preserved. For input from screen, keyboard, or se- output, the success of the operation will be indicated by the
rial devices, the status register carry bit will always be clear value in the status flag (144/$90 for tape or serial operations;
upon return. For tape input, the carry bit will be clear unless 2580/$0A14 for RS-232).
the operation has been aborted by pressing the RUN/STOP
key. For tape and serial input, the success of the operation will
be indicated by the value in the tape/serial status flag 65493 $FFD5 JLOAD
(144/$90). Due to a bug in the RS-232 portion of BASIN, the Entry point for the Kernal LOAD routine 62053/$F265, which
carry bit will be set if a byte has been successfully received; it loads or verifies a program file from tape or disk into a speci-
will be clear only if a RETURN character code is returned fied area of memory. Before calling this routine, the SETLFS
when the DSR signal is missing. The success of an RS-232 op- routine [$FFBA] must be called to establish the device number
eration will be indicated by the value in the status flag (186/$BA) and the secondary address (185/SB9) for the opera-
(2580/$0A14). tion. The logical file number (184/$B8) isn't significant for
loading. The secondary address value determines whether the
load/verify will be absolute or relocating. If bit 0 of the sec-
65490 SFFD2 JBSOUT ondary address is %0 (if the value is 0, for example), the file
Entry point for the Kernal BSOUT routine (called CHROUT in will be loaded starting at the address specified in the X and Y
previous versions of the Kernal), which sends a byte to the registers when the LOAD routine is called (a relocating load).
logical file currently specified for output, The routine is en- If the bit is %1 (if the value is 1, for example), the data will be
tered via the IBSOUT indirect vector (806/$0326), which nor- loaded starting at the address specified in the file itself (an ab-
mally points to the BSOUT routine at 61305/$EF79. You can solute load). For tape files, the secondary address specification
modify the actions of the routine by changing the vector to can be overridden by the file type. Nonrelocatable tape pro-
point to a routine of your own. See the IBSOUT entry for gram files always reload to their absolute address, even if the
details. secondary address value specifies a relocating load. The
Except to send output to the screen when the system is SETNAM routine [$FFBD] must be called to specify the length
set for default I/O, you must open a logical file to the desired (183/$B7) and address (187-188/$BB-$BC) of the associated
device and specify the file as the output target (see the entries filename. The SETBNK routine [$FF68] must be called to spec-
for the OPEN and CKOUT routines, 65472/$FFC0 and 65481/ ify the bank number where the filename can be found (199/
$FFC9, respectively). For output to tape (device 1), the charac- $C7) and the bank into which data is to be loaded (198/$C6).
ter is stored at the next available position in the cassette buffer. When the routine is called, the accumulator should hold
When the buffer is full, the data block is written to tape. For the operation type value (0/$00 for a load or any nonzero
output to RS-232 (device 2), the character is stored in the next value for a verify). If the secondary address specifies a relocat-
available position in the RS-232 output buffer. If the buffer is ing load, the X and Y registers should hold the starring ad-
608 609
^
65496 SFFD8 SFFDE 65502
65505 SFFE1 JSTOP routine to reset default I/O. Note that, despite its name, the
Entry point for the Kernal STOP routine, which checks routine doesn't actually close any files that may be open to
whether the RUN/STOP key is pressed. The routine is en- ta ne, disk, or RS-232 devices. Unclosed files may cause prob-
tered via the ISTOP indirect vector (808/$0328), which nor- lems' particularly on disks, so this routine is of limited useful-
mally points to the STOP routine at 63086/$F66E. You can n e 5 S ' s e e the Kernal CLOSE_ALL entry [$FF4A] for a routine
modify the actions of the routine by changing the vector to that properly closes all files open to a serial device.
point to a routine of your own. See the ISTOP entry for
details. 65514 $FFEA JUDTIM
The standard STOP routine returns with the status regis- Entry point for the Kernal UDTIM routine at $62968/$F5F8,
ter Z bit clear if the key is not pressed or with the bit set if it which increments the software jiffy clock, decrements the
is. Additionally, if RUN/STOP is pressed, the CLRCH routine countdown timer, and scans the keyboard column containing
[$FFCC] is called to reset default I/O, and the count of keys in the RUN/STOP key.
the keyboard buffer (208/$D0) is reset to zero.
65517 $FFED JSCRORG
65508 8FFE4 JGETIN Calls the Kernal SCRORG routine's screen editor jump table
Entry point for the Kernal GETIN routine, which retrieves a entry at 49167/$C00F. (This routine was called SCREEN in
character from the current input device. The routine is entered previous versions of the Kernal.) The routine returns infor-
via the IGETIN indirect vector (810/S032A), which normally mation on the size of the screen's current output window.
points to the GETIN routine at 61163/$EEEB. You can modify Upon return, the X register will contain the number of col-
the actions of the routine by changing the vector to point to a umns minus 1 in the current window, and the Y register will
routine of your own. See the IGETIN entry for details. contain the number of rows minus 1. The accumulator will
The standard GETIN routine checks to see whether the hold the maximum column number for the display currently
current input device is 0 (keyboard) or 2 (RS-232). If it's not active (39 for the 40-column screen or 79 for the 80-column
one of these, the BASIN routine [$EF06] is used instead. (See screen).
the BASIN entry for information on GETIN's behavior for
other devices.) For keyboard or RS-232, the retrieved character 65520 $FFF0 JPLOT
will be in the accumulator upon return, and the status register Calls the Kernal PLOT routine's screen editor jump table entry
carry bit will be clear. The value 0/$00 will be returned if no at 49176/$C018. The routine reads or sets the cursor position
character is available from the device. The contents of the Y on the active display. If it is called with the status register
register are unaffected by this routine. For RS-232, bit 3 of the carry bit clear, the value in the X register will specify the new
status flag (2580/$0A14) will be set if no characters are cursor row (vertical position), and the value in the Y register
available. will specify the column (horizontal position). The position will
be relative to the home position of the current output window
65511 $FFE7 JCLALL rather than to the upper left corner of the screen. (Of course,
Entry point for the Kernal CLALL routine, The routine is en- in the case of a full-screen output window, the default condi-
tered via the ICLALL indirect vector (812/$032C), which nor- tion, the upper left comer of the screen is the home position
mally points to the CLALL routine at 61986/SF222. You can of the window.) The carry bit will be set upon return if the
modify the actions of the routine by changing the vector to specified column or row value is beyond the right or bottom
point to a routine of your own. See the ICLALL entry for margin of the current output window. If the routine is called
details. with the carry bit set, the row number for the current cursor
The standard CLALL routine resets the number of open position is returned in the X register, and the current column
files (152/$98) to zero, then falls through into the CLRCH
612 613
65523 8FFF3 65534
6FFFE
r
number is returned in the Y register. Again, the position is rel- the stack. The address in this vector is then loaded into the
ative to the home position of the output window rather than program counter, and execution continues from that address.
the absolute home position of the screen, In the 128, this vector contains 65285/SFF05, the address of a
routine that saves the accumulator, X and Y register, and
65523 8FFF3 JIOBASE MMU configuration register values on the stack; it then config-
Entry point for the Kernal IOBASE routine at 63361/$F781, ures the system for bank 15 and jumps through the INMI vec-
which returns the base address of the system I/O block tor at 792/$0318.
(53248/$D000). The low byte, 0/$00, is returned in the X reg-
ister, and the high byte, 208/$D0, is returned in Y. 65532 $FFFC RESET
When a reset signal is detected, the processor immediately
65526-65527 $FFF6-$FFF7 Unused terminates the current operation and loads the program
Two unused bytes filled with the value 255/$FF. counter with the address in this vector, Execution then re-
sumes with the routine at that address. In the 128, this vector
65528 $FFF8 System Vector contains 65341/$FF3D, the address of a routine which config-
These locations in bank 1 are the soft reset vector, an address ures the system for bank 15, then jumps to the reset routine at
through which the reset routine [$E000] takes an indirect 57344/$E000.
jump. The ROM vector (in bank 15) is not normally used, but
it still contains the default address (57892/$E224). 65534 SFFFE IRQ/BRK
When a BRK opcode is executed or an IRQ signal is detected,
the processor completes execution of the current instruction,
8502 CPU Vectors then stores the contents of the status register and the address
One of the hardware features of the 8502 microprocessor (and of the next instruction on the stack. The address in this vector
its predecessors, the 6502 and 6510) is that certain events is then loaded into the program counter, and execution contin-
cause the processor to jump to an address held in one of the ues from that address. In the 128, this vector contains 65303/
following two-byte vectors. This implies that any system using $FF17, the address of a routine that saves the accumulator, X
one of these processors must have ROM at these addresses, or, and Y register, and MMU configuration register values on the
as in the case of the RAM banks of the 128, must have some stack; it then configures the system for bank 15, determines
method of initializing the RAM at these addresses with the ap- whether the interrupt was the result of a BRK or IRQ, and
propriate values. jumps accordingly through either the 1BRK vector at 790/S0316
An NMI (nonmaskable interrupt), triggered by a high-to- or the IIRQ vector at 788/$0314.
low transition on the processor's NMI input line, causes a
jump to the address at 65530/$FFFA. A reset, triggered when
the RESET input line is pulled low, causes a jump to the ad-
dress in 65532/$FFFC An IRQ (interrupt request), triggered
when the IRQ input line is pulled low, causes a jump to the
address in 65534/$FFFE, as does the execution of a BRK
opcode (0/$00),
Interrupts
Todd Heimarck
619
causes several things to happen. First, the 8502 automatically
pushes the current address in the program counter onto the Nonmaskable Interrupts (NMIs)
stack, as if it were executing a JSR, Next other sources of in- The other type of interrupt, the NMI, is normally caused by
terrupts are turned off, so an interrupt doesn't happen in the one of two things: pressing the RESTORE key, or performing
middle of servicing the IRQ. The accumulator and X and Y a n RS-232 operation. When an NMI occurs, the 128 jumps to
registers are pushed on the stack, and the current state of the the address held at 65530/SFFFA, which points to the Kernal
MMU configuration register at 65280/$FF00 is also put on the area at 65285/$FF05. This is a very short program, which
stack (because the computer has to return to the proper bank ends up bouncing off the RAM vector at 792-793/
setup when it's finished handling the interrupt). $0318-$0319.
The IRQ handling routine has several distinct segments. If the interrupt was triggered by the RESTORE key, the
The first sets up the current screen display mode. For example, system immediately checks to see if the RUN/STOP key was
if you've created a split graphics screen with either GRAPHIC held down at the time RESTORE was pressed. If not, the 8502
2 or GRAPHIC 4, the VIC chip has to be set up for the proper merely returns to the program it was running. If both RUN/
screen and color memory areas. Next, the keyboard is scanned. STOP and RESTORE were pressed, the RUN/STOP-RESTORE
If a key has been pressed, the appropriate character code is initialization sequence is performed, ending with a warm start
determined and stored in the keyboard buffer at 842/$034A. of BASIC (see the entry for 64064/$FA40 in Chapter 9).
If it's time for the 40-column display's cursor to blink, that's If something's happening at the RS-232 port, the incom-
taken care of. The software jiffy clock at 160-162/$A0-$A2 is ing character is processed and stored in the buffer at 3072/
clicked up a notch. The last big segment of the IRQ sequence $0C00, or the outgoing character is sent from the buffer at
is the BASIC IRQ routine, which handles a variety of sprite 3328/$0D00.
and sound support functions. For example, if you've used the
MOVSPR to put a sprite into motion, the new locations have
to be calculated and the sprite position updated. COLLISION Other Sources of IRQs
is also an interrupt-driven command, handled during the IRQ The hardware interrupt is not the only way to have an IRQ
routine. And the sound durations for the SOUND and PLAY happen. You can force the equivalent of an IRQ by including
statements are manipulated during this routine. the BRK instruction (the opcode is $00) in a machine language
program. Any of the the interrupt sources in the VIC chip or
Then, the interrupt ends. The registers are restored to CIA #1 can generate an IRQ request. These include sprite col-
their former values and the bank configuration is stored back lisions, raster interrupts, the light pen input, or any of the CIA
to 65280/$FF00. Interrupts are reenabled and the RTI instruc- timers. Of these, only the raster interrupt is used by the sys-
tion brings the 8502 back to the program it was working on. tem. As mentioned, a raster interrupt occurs when the screen
In 128 mode, the timing of the system IRQ interrupt is redraw routine reaches a certain line on the screen. The line to
tied directly to the position of the raster beam that traces the trigger the standard jiffy interrupt is off the bottom of the visi-
video screen. When the VIC chip gets to the point where it's ble area of the screen. However, the system also supports mid-
drawing a certain line on the screen, the interrupt occurs. This screen raster interrupts to manage the split-screen displays of
is a convenient way to tie in the split-screen modes. In 64 the GRAPHIC 2 and GRAPHIC 4 modes. The IRQ routine
mode, the interrupt request is generated by a hardware timer checks for mid-screen raster interrupts, and performs only the
in one of the CIA chips; this timer is not necessarily in sync screen-setup portion of the interrupt routine in that case. For
with the current position of the raster beam. an
y other type of IRQ, you must write your own handling
routine.
620
621
The first thing the 128 does at the start of an IRQ is jump
10 ; This program sets up an interrupt that checks the 40/80 key
off the processor vector at 65534/$FFFE, which takes it to the 20 ; and switches to the appropriate screen if a change has been made
short routine at 65303/$FF17. At this point, it decides whether 30 !oRG $0C00 ; Put the program at $0C0O
the interrupt was caused by software (a machine language 40 FORTY = $D7 ; 0 if set to 40 columns, 128 if 80
BRK instruction) or hardware (the raster, the timer, the light 50 KEYNDX = $D0 ; Index to how many keys are waiting in the
pen, a sprite collision, and so on). buffer
60 IRQVEC = $0314 ; Vector to the IRQ routine
A BRK instruction causes the system to proceed to a RAM 70 KEYBUF = $034A ; The keyboard buffer
vector at 790-791/$0316-$0317. The usual response to a BRK 80 SWITCH = $D505 ; Bit 7 tells us if the 40/80 switch is up or down
is to start up the built-in monitor, which is also called by the 90 ; %0 is down, %1 is up
BASIC MONITOR command. The advantage to this is plain: 170 ;
When you're writing a machine language program, you can 180 ; The first step is to save the current address in the IRQ vector
insert $00s here and there in the program (breakpoints) and 190 ;
monitor the progress of the program. 200 SEI ; Disable interrupts while the vector is being
changed
Any type of hardware interrupt sends the computer to the 210 LDA IRQVEC ; Get the low byte of the vector
vector at 788-789/$0314-$0315, where the interrupt is han- 220 CMP JUMP+1 ; See if we've done this before
dled. It's at this point that the keyboard is polled, the jiffy 230 BEQ LEAVE ; If ifs equal, jump ahead to exit the routine
clock is updated, and the various other housekeeping chores 240 STA JUMP +1 ; Else store the current IRQ vector address as the
250 LDA 1RQVEC+1 ; target of the JMP to exit from the MAIN routine
are done. 260 STA JUMP+ 2
265 ;
Writing Your Own Interrupt Handler 270 ; Now reset the vector to point to our routine at MAIN
Commodore has inserted a deliberately vulnerable point in the 275;
280 LDA #<MAIN ; Put the address of the MAIN routine
process of handling interrupts: the RAM vectors at 788-793/ 290 STA IRQVEC ; into IRQVEC
$0314-$0319. You can change these pointers to turn off inter- 300 LDA #>MAIN
rupts or to set up your own interrupt processing routine. 310 STAIRQVEC+1
The following machine language program provides a 320;
short example of how to wedge into the IRQ routine. Before 330 CLI ; We're done resetting the vector, so reenable
340 LEAVE RTS ; interrupts and exit from the setup routine
jumping to the normal IRQ handler, it checks the status of the 350;
40/80 DISPLAY key and switches screens if the key setting 400 MAIN = •
doesn't match the currently active screen. 420 ; First, check the status of the 40/80 switch
First, the address currently in the IRQ vector (788-789/ 430 ;
$0314-$0315) is stored as the target address of the JMP that 440 LDA FORTY ; Value is either 0 (40 columns) or $80 (80 columns)
450 EOR SWITCH ; Exclusive-OR with the 40/80 switch flag (bit 7)
ends our own routine. Then the address of our MAIN routine 460 ; if (he status register N flag is %0,
is stored into the IRQ vector. And that's the end of the in- 470 BPL CHANGE ; go ahead and switch displays
staller routine. 480 JUMP JMP $FFFF ; Else jump to the normal IRQ routine
From then on, whenever an IRQ interrupt occurs, the 128 490 ; Note: We never really jump to address $FFFF.
jumps to our custom routine, because the vector has been 495 ; The installation routine changes the $FFFF to the
500 ; address of the normal IRQ routine
changed. Within our routine, the 40/80 switch is checked and 510 ;
if it has been changed, an ESCape (CHR$(27)) and X are 520 CHANGE LDA #27; Put the code for the ESCape key
placed in the keyboard buffer. Whether or not the 40/80 DIS- 530 STA KEYBUF ; into the keyboard buffer, along with
PLAY key has been pressed, we finish the routine by execut- 540 LDA #"X" ; the letter X (ESC X means switch
1
ing a JMP to the normal IRQ routine.
622
550
560
570 JMP
580 LDA
STA JUMP
KEYBUF-1
KEYNDX
#2 ; so
Finish
active
We're
tell putting
displays)
the
up by
128going
two
that keys
2tokeys
the
in are
normal
the pressed
buffer
IRQ routine
623
Appendix B
BASIC
1. Perhaps the most significant bug in BASIC 7.0 is that,
contrary to what the manuals claim, you can't use negative
relative parameters in graphics statements. For example, ac-
cording to the System Guide, DRAWTO - 5 , - 5 should be a
valid statement to draw a line five pixels up and five pixels
left of the current pixel cursor position. Instead, it causes an
ILLEGAL QUANTITY error. The graphics routines themselves
are set up to handle such coordinates, but the routine which
evaluates parameters uses a subroutine that checks the sign of
the value and causes an error if the value is negative.
2. An attempt to OPEN a logical file to an RS-232 device
such as a modem will result in a DEVICE NOT PRESENT er-
ror if x-line handshaking is specified. This is the result of the
Kernal RS-232 OPEN bug described below.
3. An attempt to use INPUT* with a logical file specified
for device 3 (the screen) will not work because of the Kernal
screen BASIN bug mentioned below.
4. In strings for the PLAY statement, any number of digits
can follow a U (volume) command, but only the last one
counts. Also, a digit alone, with no other command, is the
625
same as U followed by that digit. All four of the following 9. All BASIC disk commands automatically add the drive
statements are equivalent: 0 specification if no other drive number is specified, except for
PLAY "VI U7 ABCDE" CATALOG and DIRECTORY. Although Commodore drives
PLAY "VI U1234567 ABCDE" will supply the directory of drive 0 by default, failing to spec-
PLAY "VI U7777 ABCDE" ify a drive number sets up conditions for the infamous 1541
PLAY "VI 7 ABCDE" drive Save-with-Replace bug. Thus, it's safest to add a DO
5. The RSPRITE function accepts sprite number param- after each CATALOG or DIRECTORY.
eters up to 16, even though only 1-8 are valid. 10. In the BASIC disk commands, the ON U parameter
6. The RWINDOW function doesn't return values stated can be specified any number of times; only the last occurrence
in the System Guide. The manual states that RWINDOW(O) re- counts. CATALOG ON U6 ON U7 ON U8 is equivalent to
turns the number of lines in the current output window and CATALOG ON U8.
RWINDOW(l) returns the number of rows. Actually, 11. Commodore literature fails to describe the RREG
RWINDOW(O) returns the number of rows minus 1 in the out- statement included in BASIC 7.0. The proper format is RREG
put window, and RWINDOW(l) returns the number of col- variable 1, variable 2, variable 3, variable 4. The specified vari-
umns minus 1. ables will be set to the values in locations 6, 7, 8, and 5, re-
7. Commodore literature claims that the default scaled spectively. These locations hold the accumulator, X register, Y
size for a standard bitmapped screen (if you use SCALE 1 register, and status register values from the last time the
without additional parameters) is 1023 X 1023. Actually, it's JSRFAR routine was used, such as upon return from the most
1024 X 1024, but that's relatively trivial. A more serious prob- recent SYS statement. Any of the variables may be omitted, so
lem with scaling is that it doesn't work as claimed for multi- RREG AC,,,SP and RREG ,,YR are valid statements.
color (GRAPHIC 3 or GRAPHIC 4) screens. The default scaled 12. BASIC 7.0 allows LIST to be used as a statement
multicolor screen is also 1024 X 1024, not 511 X 511 as within a program, but the RENUMBER statement will not re-
claimed in the System Guide. When you supply scaling factors number any line numbers that may follow LIST in a program
for a multicolor screen, you must use twice the desired hori- being renumbered. This is a trivial oversight, since occasions
zontal scaling value. For example, to scale the multicolor dis- to use LIST within a program are quite rare,
play to 256 X 256, you must use SCALE 1,512,256. The
horizontal factor must be greater than 320 to prevent an ILLE-
GAL QUANTITY error. Kernal
8. The SCNCLR routine doesn't properly fill color mem- 1. The BASIN routine will not accept input from the
ory for a GRAPHIC 4 (split multicolor bitmapped and text) screen because it fails to properly mark the end of the input
screen. That is, the routine fails to fill color memory with the string. Refer to the discussion of the routine at 49819/$C29B
current color source 3 value. Since that routine is also used for in Chapter 7 for more information and a solution to the
the clear option of the GRAPHIC statement, GRAPHIC 4,1 problem.
won't properly initialize color memory either. For multicolor 2. Although it isn't mentioned in the manuals, ESC ESC
bitmapped mode, color memory determines the color of pixels is accepted as a synonym for ESC O (cancel quote mode).
with % 11 bit patterns. The solution is to follow any GRAPHIC 3. The screen editor CINT and SWAPPER routines copy
4 statement with a SCNCLR 3, which does properly fill the one too many bytes when initializing or exchanging the con-
color memory area. As part of the same bug, color memory is tents of the screen editor variable table at 224-249/$E0-$F9.
unnecessarily filled for SCNCLR 2 or GRAPHIC 2,1, but that As a result, the contents of the otherwise unused locations
has no visible effect because color memory is not used in stan- 250/$FA and 256O/$0A5A are overwritten whenever the
dard bitmapped mode. screen is initialized or switched.
626 627
Appendix C
Character Codes
The 128 has two separate sets of 256 characters. The set that
is normally activated when the computer is turned on is called
the uppercase/graphics set. It has only uppercase (capital) let-
ters, but includes many graphics characters. The alternative
lowercase/ uppercase set has both lowercase and uppercase
letters, but includes substantially fewer graphics characters. It
is useful for creating more attractive text displays, and is es-
sential for tasks like word processing. You can switch man-
ually between sets by pressing the SHIFT and Commodore
keys simultaneously. You can also switch to the
lowercase/uppercase set within a program by printing charac-
ter 14—PRINT CHR$(14). To switch back to the normal
uppercase/graphics set, print character 142,
In the 40-column display mode, switching character sets
affects all characters currently on the screen. For example, up-
percase letters printed from the uppercase /graphics set will
change to lowercase characters after CHR$(14) is printed.
However, any character set switching in 80-column mode af-
fects only those characters printed after the switch. In this
case, uppercase letters printed from the uppercase/graphics set
will remain in uppercase after a CHR$(14) is printed.
The lowercase/uppercase character set has two identical
groups of uppercase letters, characters 97-122 and characters
193-218. When this set is being used, PRINT CHR$(97) and
PRINT CHR$(193) both cause an A to be displayed on the
screen. However, you should be aware that the ASC function
always returns values from the higher group—in lowercase/
uppercase, PRINT ASC("A") always gives 193 instead of 97.
628 629
In machine language, the Kernal GETIN routine also returns pec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
values 193-218 for shifted letters in the lowercase/uppercase & &
38 26
set.
The following table lists the codes for the 128 character 39 27
40 28 ( (
25, 26, 128, 131, and 132. 29 ) )
41
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set 42 2A * *
2 02 underline on3 43 2B + +
5 05 white 44 2C r
7 07 bell tone2 45 2D - -
8 08 disable SHIFT-Commodore3 46 2E •
9 09 tab' 47 2F / /
enable SHIFT-Commodore3 48 30 0 0
10 0A linefeed2 49 31 1 1
11 0B disable SHIFT-Commodore* 50 32 2 2
12 OC enable SHIFT-Commodore2 51 33 3 3
13 0D RETURN 52 34 4 4
14 0E switch to lowercase 53 35 5 5
6 6
15 OF flash on1 54 36
cursor down 55 37 7 7
17 11
56 38 8 8
18 12 reverse on
57 39 9 9
19 13 home
58 3A *
20 14 delete • •
24 18 tab set/clear2 59 3B
60 3C <
27 IB ESCape <
61 3D =
28 1C red =
62 3E >
29 ID cursor right >
63 3F ? ?
30 IE green
64 40 @ @
31 IF blue
65 41 A a
32 20 space
66 42 B b
33 21 ! !
67 43 C c
34 22
68 44 D d
35 23 # #
69 45 E e
36 24 $ $
70 46 F f
37 25 % %
631
630
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
71 47 G g 104 68 LL H
72 48 H h I
69
73 49 I i
105
E J
74 4A
106 6A ffl
J 6B K
75 4B K
j
*
107
E
k 108 6C LJ L
76 4C L 1 109 6D \ M
77 4D M m 110 6E Z N
78 4£ N n 111 6F r O
79
80
4F
50
O
P
o 112 70 n• P
p 113 71 Q
81 51 Q q 114 72 y R
82 52 R * 115 73 S
83 53 r
S 116 74 I] T
84 54 u
T t 117 75 r^
85 55 U u 118 76 V
86 56 w
V V 119 77 ip
87 57 w w 120 78 x
88
89
58
59
X X 121 79 r Y
Y y 122 7A z
90
91
5A
5B
z 2 7B s +
[ [
L
124 7C B
92 5C £ E 125 7D [E •D
93 5D
94 5E
] 1 7E SB
I r 127 7F S3
95 5F 4-
129 81 orange4
96 60 B & dark purple1
97 61
* A 130 82 underline off
98 62
DD B 133 85 Fl
99 63 C 134 86 F3
100 64 a D 87 F5
101 65 H E 88 F7
102
103
66 s F 137 89 F2
67
DD G 8A F4
632 633
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
139 8B F6 170 AA 3 []
140 8C F8 171 AB [B IB
141 8D SHIFT-RETURN 172 AC Ld Q
142 8E switch to uppercase 173 AD ffl ffl
143 8F flash off1 174 AE ffl T
144 90 black 175 AF U •
145 91 cursor up 176 B0 ffl ffl
146 92 reverse off 177 Bl ffl ffl
147 93 clear screen 178 B2 &H ffl
148 94 insert 179 B3 m m
149 95 brown4 180 B4 CJ
dark yellow1 181 B5 C ID
150 96 light red 182 B6 LI Ll
151 97 dark gTay4 183 B7
dark cyan1 184 B8 H n
152 98 medium gray 185 B9 U y
153 99 light green 186 BA • ~V\
154 9A light blue 187 BB H B
155 9B light gray 188 BC L3 1
156 9C purple 189 BD ffl ffl
157 9D cursor left 190 BE H H
158 9E yellow 191 BF fij BJ
159 9F cyan 192 CO H H
160 A0 SHIFT-space 193 Cl H A
194 C2 J| B
161 Al 1 E 195 C3 H C
162 A2 y y
163 A3 • — 196 C4 S D
• 197 C5 H E
164
165
A4
A5 ri r 198
199
C6
C7
H
li
F
G
166 A6 Si 200 C8 U H
167 A7 IH 1 201 C9 B I
168 A8 V. •A
169 A9 n 202 CA f? J
634 635
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
203 CB ffl K
236 EC H ~~m
204 CC t] L
237 ED t ^
205 CD k| M
238 EE ffl SI
206 CE g] N
239 EF U U
207 CF |-j 0
240 F0 _T L^
208 DO 3 P
209 DI \m\ Q
241 FI a m
210 D2 H R 242 F2 H ffl
211 D3 m S 243 F3 tfj J!
212 D4 11 244 F4 G I !
T
213 D5 H U 245 F5 [I II
246 F6 | ||
214 D6 X V
247 F7 H
215 D7 [g w
248 F8 H H
216 D8 t X
249 F9 y M
217 D9 [J Y
250 FA Ul ^
218 DA 3 Z
251 FB kJ B
219 DB + +
252 FC " H
220 DC BC B
253 FD B ?J
221 DD fl If
254 FE Fl
222 DE iil g| 255 FF ifl S?
223 DF ^ jg
Notes
224 E0 1. For 80-column display only
2. For 128 mode only
225 El |J |j 3. For 64 mode only
226 E2 y y 4. For 40-colunm display only
227 E3 ^ •
228 E4 •
229 E5. O Hi
231 E7 1 []
232 E8 ii ^
233 E9 B 5g
234 EA El •
235 EB DB Lfe
637
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
Screen Codes
There are 256 screen codes for each character set; codes 24 18 X X
1 01 A a 34 22
2 02 B b 35 23 # #
3 03 C c 36 24 $ $
4 04 D d 37 25 % %
5 05 E e 38 26 & &
6 06 F i 39 27
7 07 G g 40 28 ( (
8 08 H h 41 29 ) )
9 09 I i 42 2A
10 0A J j 43 2B + +
11 0B K k 44 2C t t
12 0C L 1 45 2D - -
13 0D M m 46 2E *
14 0E N n 47 2F / /
48 30 0 0
15 OF O o
16 10 P p 49 31 1 1
17 11 Q q 50 32 2 2
18 12 R r 51 33 3 3
19 13 S s 52 34 4 4
20 14 T t 53 35 5 5
21 15 U u 54 36 6 6
22 16 V v 55 37 7 7
23 17 W w 56 38 8 8
639
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
57 39 9 9
90 5A ffl Z
58 3A :
91 5B * +
59 3B ; ;
92 5C £1 £J
60 3C < <
93 5D [B T
61 3D = = 1
94 5E ff ^
62 3E > >
95 5F 15 ^
63 3F ? ?
96 60 SHIFT-space
64 40 g B
97 61 H |]
65 41 • A
98 62 y H
66 42 I]] B
99 63 n
67 43 H C
100 64 • •
68 44 g D
ioi 65 r r
69 45 —' E
70 46 — F
103 67 fl •
71 47 |] G
104 68 ki kaJ
72 48 [11 H
105 69 Fl ^
73 49 E I
106 6A • ]
74 4A V j
107 6B [B |_£
75 4B ffi K
108 6C ;H .
76 4C C L
109 6D [5 ^
77 4D SJ M
HO 6E h ffl
78 4E 2 N
79 4F C 0
in 6F ^. y
80 50 ^ P
112 70 ffl ffl
81 51 IB] Q
113 71 ffl ^
82 52 Q R H4 72 ffl T
83 53 W S H5 73 3] ffi
84 54 Hj T 116 74 Cl C
85 55 ffl U H7 75 IJ I
86 56 J£ V US 76 I d
87 57 O W ii9 77 n
88 58 |5| X
89 59 d Y
121 79 U Q
122 7A • |Z
640
641
Dec Hex Uppercase/Graphics Set Lowercase/Uppercase Set
123 7B •
124 7C
125 7D ffl
126 ?E F]
127 7F n
Keycodes
The 128 keyboard is arranged electrically as a matrix of 11 col-
umns X 8 rows of keys. Every 1/60 second, the computer
scans the keyboard to see if a key is pressed. If a key is
pressed, the keyscan routine generates a value that corre-
sponds to the key's position in the matrix. (The formula is
keycode = column * 8 + row, where column has a value from
0 to 10, and row has a value from 0 to 7.) If no key is pressed,
a value of 88 is generated. This value is stored in location 212.
Location 213 will also hold the same value. The contents of
this location can be used to determine which key is currently
being pressed, as an alternative to using GET (or the Kernal
GETIN routine inmachine language). For example, these two
lines have the the same effect—to pause the program until
any key is pressed:
100 GET K$:IF K$="" THEN 100
100 IF PEEK(212)=88 THEN 100
Figure C-l gives the keyscan codes for the 128 keyboard.
Notice that the figure shows no values for the left and' right
SHIFT keys, CONTROL, the Commodore key, and ALT. They
are the keys which use the missing codes 15, 52, 58, 61, and
80, respectively. These keys are detected later in the keyscan
routine, and location 211 is used to record their status. The
values found in that location are as follows:
No shift key pressed 0
SHIFT 1
Commodore 2
CONTROL 4
ALT 8
CAPS LOCK 16
642 643
Appendix D
64/128 Memory
Map Cross
Reference
The following list provides a cross reference of the Commo-
dore 64 and Commodore 128 memory maps. In addition to
the RAM locations shown, all I/O chips appear in the 128 at
the same addresses as in the Commodore 64. (When the 128
is used in Commodore 64 mode, the two extra VIC chip regis-
ters and the VDC 80-column chip are still available, although
they must be programmed directly, since there are no routines
to support them.) Also, the Kernal jump table at 65409-65525/
$FF81-$FFF5 is common to both the Commodore 64 and 128.
649
Commodore 64 address Commodore 128 address
s 0/$00 0/$00
Function
Processor on-chip I/O port data direction register
l/$01 l/$01 Processor on-chip I/O port data register
3-4/$03-$04 4474-4475/$117A-$117B Vector: Routine to convert a number from floating point to
signed integer
5-6/$05-$06 4476-4477/$117C-$117C Vector: Routine to convert a number from integer to floating
point
7/$07 9/$09 Search character for scanning BASIC text input
8/$08 10/$OA Search character for statement terminator or quote
9/$09 11/$OB Column position of the cursor before the last TAB or SPC
1O/SOA 12/$0C BASIC LOAD/VERIFY flag
11/$OB 13/$0D [ndex into the text input buffer / number of array subscripts
12/$0C H/$0E Flag for routines that locate or build an array
13/$0D 15/$0F Flag: Type of data {string OT numeric)
14/$0E 16/$10 Flag: Type of numeric data (integer or floating point)
15/$0F 17/$11 Flag for LIST, garbage collection, and program tokenizatiort
16/$10 I8/$12 Flag: Subscript reference to an array or user-defined function call
(FN)
17/$11 19/$13 Input source flag (GET, READ, or INPUT)
18/$12 20/$14 Flag: Sign of the result of the TAN or SIN function
19/$13 2I/$15 Current I/O channel {CMD logical file) number
20-21/$14-$15 22-23/$16-$17 Integer line number value
22/$16 24/$18 Pointer to the next available space in the temporary string stack
23-24/$17-$18 25-26/$19-$1A Pointer to the address of the last string in the temporary string
stack
25-33/$19-$21 27-35/$lB-$23 Descriptor stack for temporary strings
34-37/$22-$25 36-39/$24-$27 Miscellaneous temporary pointers and save area
38-42/$26-$2A 40-44/$28-$2C Floating point multiplication work area
43-44/$2B-$2C 45-46/$2D-$2E Pointer to the start of BASIC program text
45-46/$2D-$2E 47-48/$2F-$30 Pointer to the start of the variable storage area
47-48/$2F-$30 49-50/$31-$32 Pointer to the start of the array storage area
49-50/$31-$32 51-52/$33-$34 Pointer to the start of the area available for string storage
BASIC Keyword
Index
The following table lists all of the BASIC 7.0 keywords in al-
phabetical order, along with their corresponding tokens and
the addresses of the routines called to perform each token's
operation.
656 657
Keyword Token Address Keyword Token Address
DCLOSE 254/$FE+15/$0F 41327/$A16F LOCATE 23O/SE6 26965/$6955
DEC 2O9/$D1 32886/$8076 LOG 188/$BC 35274/$89CA
DEF 150/$96 34042/$84FA LOOP 236/$EC 24714/$608A
DELETE 247/$F7 24199/$5E87 MID$ 202/$CA [3]
DIM 134/$86 22651/$587B MONITOR 250/$FA 45056/$B000
DIRECTORY 238/$EE 41086/$A07E MOVSPR 254/$FE + 6/$06 27846/$6CC6
DLOAD 240/$F0 41383/$A1A7 NEW 162/$A2 20950/$51D6
DO 235/$EB 24544/$5FE0 NEXT 130/$82 22516/$57F4 [4]
DOPEN 254/$FE+13/$0D 41245/$A11D NOT 168/$A8 31024/$7930
DRAW 229/$E5 26519/$6797 OFF 254/$FE + 36/$24 18502/$4846 [5]
D5AVE 239/$EF 41356/$A18C ON 145/$91 21411/$53A3 [6]
DVERIFY 254/$FE + 20/$14 4138O/$A1A4 OPEN 159/$9F 37261/$918D
ELSE 213/$D5 21393/$5391 OR 176/$B0 19590/$4C86
END 128/$80 19405/$4BCD PAINT 223/SDF 25000/$61A8
ENVELOPE 254/$FE + 10/$OA 28865/$70Cl PEEK 194/$C2 32965/$80C5
ERR$ 211/$D3 33014/$80F6 PEN 206/$CE+4/$04 33454/$82AE
EXIT 237/$ED 24633/$6039 PLAY 254/$FE + 4/$04 28129/S6DE1
EXP 189/IBD 36915/$9033 POINTER 206/$CE + 10/$0A 33530/$82FA
FAST 254/$FE + 37/$25 30643/$77B3 POKE 151/S97 32997/$80E5
FETCH 254/$FE + 33/$21 43556/$AA24 POS 185/$B9 34000/$84DO
FILTER 254/$FE + 3/$03 28742/$7046 POT 206/$CE + 2/$02 33357/$824D
FN 165/$A5 34107/$853B PRINT 153/$99 21850/$555A
FOR 129/$81 24057/$5DF9 PRINT* 152/$98 21818/$553A
FRE 184/$B8 32768/$8000 PUDEF 221/$DD 24372/$5F34
GET 161/$A1 22034/$5612[2] QUIT 254/$FE + 30/$lE 18502/$4846 [5]
GO 203/$CB 23101/$5A3D RCLR 205/$CD 33179/$819B
GOSUB 141/$8D 22991/$59CF RDOT 208/$D0 39692/$9B0C
GOTO 137/$89 23003/$59DB READ 135/$87 22185/S56A9
GRAPHIC 222/$DE 27482/$6B5A RECORD 254/$FE + 18/$12 41687/$A2D7
GSHAPE 227/$E3 25997/$658D REM 143/$8F 21149/$529D
HEADER 241/$F1 4I575/$A267 RENAME 245/$F5 41838/$A36E
HELP 234/$EA 22918/$5986 RENUMBER 248/$F8 23288/$5AF8
HEX$ 210/$D2 33090/S8142 RESTORE 23242/$5ACA
140/$8C
IF 21189/$52C5
I39/S8B RESUME 214/$D6 24418/$5F62
INPUT 133/$85 22H4/$5662 RETURN 142/$8E 21090/$5262
INPUT# 132/$84 22088/$5648 RGR 204/$CC 33154/$8182
INSTR 212/SD4 39361/S99C1 RIGHTS 201/$C9 34314/$860A
INT 181/$B5 36091/$8CFB RND 187/$BB 33844/$8434
JOY 207/$CF 33283/$8203 RREG 254/$FE + 9/$09 22717/$58BD
KEY 249/$F9 24842/$610A RSPCOLOR 206/$CE + 7/$07 33633/$8361
LEFTS 200/$C8 34262/$85D6 RSPPOS 206/$CE + 5/$05 33687/$8397
LEN 195/$C3 34408/$8668 RSPRITE 206/$CE + 6/$06 33566/$831E
LET 136/$88 21446/$53C6 RUN 138/$8A 23195/$5A9B
LIST 155/$9B 20706/$50E2 RWINDOW 206/$CE + 9/$09 33799/$8407
LOAD 147/$93 37164/$912C SAVE 148/$94 37138/$9112
658
659
Keyword Token Address Address
Keyword Token
SCALE 233/$E9 26976/$6960
SCNCLR < 179/$B3 19638/$4CB6
232/$E8 2 725 7/$ 6A 79 178/$B2 19638/$4CB6
SCRATCH 242/$F2 41633/$A2A1 > 177/$B1 19638/$4CB6
SGN 180/$B4 35941/$8C65
srN K 255/$FF [12]
191/$BF 37904/$9410
SLEEP 254/$FE + ll/$0B 27607/$6BD7
SLOW 254/$FE + 38/$26 30660/$77C4
SOUND 218/$DA 29164/$71EC
SPC( 166/$A6 Notes:
[7]
SPRCOLOR 254/$FE + 8/$08 29072/$7190
1. Normally handled during IF execution. When encountered
SPRDEF 254/$FEH-29/$lD 29554/$7372 outside IF processing, the target routine merely prints a
SPRITE 254/$FE + 7/$07 27727/$6C4F SYNTAX ERROR message.
SPRSAV 254/$FE + 22/$16 30444/$76EC 2. There are no separate tokens for the keywords GET* and
SQR 186/$BA 36791/$8FB7 GETKEY; both are handled as special cases during GET
SSHAPE 228/$E4 25643/$642B execution. GET* is represented by a GET token followed
STASH 254/$FE + 31/$lF 43551/$AA1F by a # character (code 35/$23). GETKEY is represented by
STEP 169/$A9 [8] a GET token followed by a KEY token (249/SF9).
STOP 144/$90 19403/$4BCB
STR$ 3. Can be used as either a statement or a function. The rou-
196/$C4 34222/$85AE tine at 22785/$5901 handles processing as a statement;
SWAP 254/$FE + 35/$23 43561/$AA29
SYS when a function, the routine at 34332/S861C is used.
158/$9E 22661/$5885
TAB(
TAN
163/$A3
192/$C0
m
37977/$9459
4. Can also be used in conjunction with the RESUME
statement.
TEMPO 254/$FE + 5/$05 28631/$6FD7
5. Defined but not implemented. The target routine merely
THEN 167/$A7 [9]
prints an UNIMPLEMENTED COMMAND ERROR
TO 164/$A4 message.
TRAP [10]
215/$D7 24397/$5F4D 6. Can also be used in conjunction with most disk commands
TROFF 217/$D9 to specify the device (unit) number.
TRON 22711/$58B7
216/$D8 22708/$58B4 7. Processed during PRINT execution.
UNTIL 252/$FC 8. Processed during FOR execution.
USING
USR
251/$FB
I83/$B7
m4632/$1218 9. Processed during IF execution.
VAL 197/$C5 10. Processed during the execution of several other keywords
VERIFY 32842/$804A which accept TO as part of a valid statement: DRAW, FOR,
149/$95 37161/$9129
VOL 219/$DB GO, and assorted disk commands (BACKUP, BSAVE,
WAIT 29125/$71C5 CONCAT, COPY, and RENAME).
146/$92 27693/$6C2D
WHILE 253/$FD 11. Processed during DO or LOOP execution.
WIDTH [11]
254/$FE + 28/$lC 29110/$71B6
12. Processed during the operand evaluation routine (EVAL),
WINDOW 254/$FE + 26/$lA 30935/$78D7.
XOR 29388/$ 72CC
206/$CE + 8/$08 33761/$83E1
+ 170/$AA 34888/$8848
171/$AB
* 172/$AC
34865/$8831
35367/$8A27
/ 173/$ AD 35660/$8B4C
174/$AE
36801/S8FC1
660
661
highest quality programs like Number
Quest. Address File, Treasure Hunt.
Castle Dungeon, Vocab Builder,
SpeedScript, and hundreds of other
educational, home finance, and game
More fun...More challenge... programs.
Mote all new programs So subscribe today—and unleash
each and every month. the hidden power of your Commodore
computer, Return the card below—or
Subscribe to COMPUTEVs Gazette call 1-800-247-5470 (in Iowa. 1-800-
through this special money-saving in- 532-1272). Do it now.
troductory offer—and start unleashing
the full power of your Commodore
computer.
Month after month, look to
COMPUTERS Gazette to deliver the
latest inside word on everything from
short programming tips to the best
new software. Our expert analysis and
insights mean you have more fun...get
more enjoyment...more of what you
bought your computer for.
As a subscriber, you also receive
up to 20 all-new, action-packed pro-
grams each month. Every big issue of
COMPUTEVs Gazette comes complete
with a steady supply of the most
useful, the most entertaining, the
Subscription
Savings Card
i YES!
n Payment enclosed • Bill me • Charge my VISA/MasterCard
COMPUTE'S
Index of Locations
You can search far and wide and you
simply want find a better magazine...a
better source of insightful, stimulating,
usable information for your Com-
Add it up for yourself. Where else
can you get exciting programs each
month...expert advice...insightful
analysis...up-to-the-minute software
and Routines
modore computer than COMPUTERS reviews and so much more—all for
Gazette. just $18.
COMPUTE'S Gazette works So why wait. Subscribe now to
harder...digs deeper...researches COMPUTEfs Gazette—and get the
Chapter 2: Common Working Storage
further—all to help guarantee that you most from your Commodore computer. so Data direction register for processor's on-chip I/O
get the absolute most from your Com- Return card below—or call 1-SO0- port
modore. 247-5470 (in Iowa. 1-800-532-1272). 1 $01 Data register for processor's on-chip I/O port
Subscribe today and each and ev- 2 $02 Target bank for JMPFAR and JSRFAR
ery month you 11 receive up to 20 all- 3-4 $03-$04 Target address for JMPFAR and JSRFAR
new action-packed programs. That's up 5 $05 Status register storage for JMFFAR and JSRFAR
to 200 programs each year—game pro- 6 $06 Accumulator storage for JMPFAR and JSRFAR
grams...education programs...home ap- 7 $07 X register storage for JMPFAR and JSRFAR
plications programs...personal and g $08 Y register storage for JMPFAR and JSRFAR
budgeting programs...sorting and filing 9 $09 Stack pointer storage for JSRFAR and monitor
programs. 9 $09 Working storage for various routines
10 $0A Working storage for various routines
11 $0B Current screen column for TAB and SPC calculations
12 $0C BASIC LOAD/VERIFY flag
13 $0D Working storage for various routines
14 $0E Array dimension flag
15 $0F Variable type flag
16 $10 Numeric type flag
17 $11 Working storage for various routines
18 $12 Integer/subscript prohibit flag
19 $13 Input source flag
20 $14 Comparison type flag/Tangent sign flag
21 $15 Logical file number for BASIC input and output
22-23 $16-$17 Integer value of ASCII digit string
24 $18 Pointer into temporary string descriptor stack
25-26 $19-$1A Pointer to most recent descriptor stack entry
27-35 $lB-$23 Temporary string descriptor stack
NO POSTAGE Multipurpose address pointer
36-37 $24-$25
NECESSARY 38-39 $26-$27 Multipurpose address pointer
IF MAILED 40-44 $28-$2C Temporary storage area for multiplication and
IN THE division
UNITED STATES 45-46 $2D-$2E Start-of-BASIC-program pointer
47-48 $2F-$30 Start-of-variables pointer
BUSINESS REPLY MAIL 49-50
51-52
$31-$32
$33-$34
Start-of-arrays pointer
Start-of-free-memory pointer
FIRST CLASS PERMIT NO. 7551 DES MOINES. lA 53-54 $35-$36 Bottom-of-string-space pointer
55-56 $37-$38 Temporary pointer into the string pool
POSTAGE: WILL BE PAID BY ADDRESSEE 57-58 $39-$3A Top-of-memory pointer
59-60 $3B-$3C Current BASIC line number
Pointer for main BASIC character retrieval routine
COMPUTERS Gazette 61-62
63-64
65-66
$3D-$3E
$3F-$40
$41-542
Working pointer for varoious routines
line number of current DATA statement
PO Box 10775
67-68 $43-$44 Pointer to next DATA item
Des Moines, IA 50347-0775 69-70 $45-$46 Text pointer for input
71-72 $47-$48 Current variable name
663
IJ.I.II II..J..M...IM., j...n. < .i.i.i...r.ii
73-74 $49-$4A Pointer to variable descriptor 150 $96 Cassette block synchronization count
75-76 $4B-$4C Variable descriptor pointer and working storage 151 $97 Temporary register storage
77-78 $4D-$4E Temporary storage for text pointer 152 $98 Number of files currently open
79 $4F Relational operator flag 153 $99 Current input device
80-81 $50-$51 Defined function pointer and working pointer 154 $9A Current output device
80-84 $50-$54 Temporary storage for floating point value 155 $9B Tape character parity
82-83 $52-$53 Variable address storage and working pointer 156 $9C Tape dipole received flag
85 $55 HELP flag 157 $9D Kemal message control flag
86-88 $56-$58 BASIC function execution vector 158 $9E Tape pass 1 error-log pointer
89-93 $59-$5D Floating point work area 159 $9F Tape pass 2 error-log pointer
90-91 $5A-$5B Multipurpose working pointer 160-162 $A0-$A2 Software jiffy clock
92-93 $5C-$5D Multipurpose address pointer 163 $A3 Tape: Count of bits to be read or written
93-95 $5D-$5F String length and pointer for MID$ Serial: EOI flag
94-98 $5E-$62 Temporary storage for floating point value 164 $A4 Tape: Half-cycle indicator
94-95 $5E-$5F Working pointer for garbage collection Serial: Byte received
95 $5F Decimal point position 165 $A5 Tape: Leader synchronization countdown
96-98 $60-$62 Substring length and pointer for MID$ Serial: Count of bits to send
96-104 $60-$68 Monitor zero-page pointers and working storage 166 $A6 Pointer into cassette buffer
97-98 $61-$62 Multipurpose address pointer 167 $A7 Tape: Leader clipole count/block indicator
99-103 $63-$67 Floating point accumulator 1 RS-232: Current bit received
304 $68 Sign of FAC1 168 $A8 Tape: Half-cycle indicator for writing/error flag for
105 $69 Sign flag during conversion/Count of terms in series reading
evaluation RS-232: Count of bits remaining to be received
106-110 $6A-$6E Floating point accumulator 2 169 $A9 Tape: Word marker flag/half-cycle flag
111 $6F Sign of FAC2 RS-232: Start bit received flag
112 $70 Sign comparison flag 170 $AA Tape: Read phase flag
112-113 $70-$71 Multipurpose address pointer RS-232: Assembly byte for received bits
113 $71 Rounding flag for FAC1 171 $AB Tape: Leader dipole counter / checksum work byte
114-115 $72-$73 Multipurpose address pointer and working storage RS-232: Received byte parity
116-117 $74-$75 Step value for autoincrement 172-173 $AC-$AD Kernal working address pointer
118 $76 Graphics area flag 172-175 $AC-$AF Work area for disk booting
119 $77 General purpose working storage 174-175 $AE-$AF Kemal working storage: Used to hold the ending ad-
120 $78 String offset pointer dress for SAVE [$F53E]
121 $79 Multipurpose temporary storage 176 $B0 Kernal address pointer
122 $7A Index into input buffer for monitor 177 $B1 TEMP
122-124 $7A-$7C Descriptor for disk error string DS$ 178-179 $B2-$B3 Pointer to cassette buffer
125-126 $7D-$7E BASIC runtime stack pointer 180 $B4 Tape: leader/data flag
127 $7F RUN mode flag RS-232: Count of bits transmitted
128 $80 Decimal point position 181 $B5 Taper Leader completed flag
128-129 $80-$81 Parameter flags for DOS support commands RS-232: Next bit to send
130 $82 Storage for processor stack pointer 182 $B6 Tape: Error flag / end of block flag
131 $83 Color source for current graphics command RS-232: Character being sent
132 $84 Color source 2 storage 183 $B7 Length of current filename
133 $85 Color source 3 storage 184 $B8 Logical file number
134 $86 Current foreground color (source 1) storage 185 $B9 Current secondary address
135-136 $87-$88 Horizontal scaling factor 186 $BA Current device number
137-138 $89-$8A Vertical scaling factor 187-188 $BB-$BC Pointer to start of filename
139 $8B PAINT mode flag 189 $BD Tape: Byte read from tape / byte to be written to tape
140-141 $SC-$8D Address pointer for graphics routines RS-232: Parity calculation working storage
142-143 $8E-$8F Temporary storage for graphics routines Serial: Current byte during burst mode load
144 $90 Status flag for tape and serial bus operations 190 (BE Block count
145 $91 Scan value of STOP key column 191 $BF Drive number (ASCII) for PHOENIX
146 $92 Tape timing adjustment factor 192 $C0 Tape motor interlock
147 $93 Kernal load/verify flag/Monitor operation flag 193-194 $C1-$C2 Kernal work pointer: Used to hold starting address for
148 $94 Serial deferred character flag save
K9 $95 Serial character buffer 195-196 $C3-$C4 Kemal work pointer (starting address for load)
664 665
197 $C5 Bit read from tape / checksum of block written to 311-507 $0137-$01FB Stack space used by BASIC
tape 512-672 J0200-S02AO BASIC and monitor input buffer
198 $C6 Bank where data for save, load, or verify is found 673 S02A1 Unused
199 $C7 Bank where filename for open, save, load, or verify is 674-686 $02A2-$02AE Retrieves a value from any bank
found 687-701 $02AF-$02BD Stores a value in any bank
200-201 $C8-$C9 Pointer to RS-232 input buffer 702-716 $02BE-$02CC Compares the accumulator contents against a value
202-203 $CA-$CB Pointer to RS-232 output buffer from any bank
204-205 $CC-$CD Pointer to current keyboard decode table 717-738 $02CD-$02E2 Calls a subroutine in any bank
206-207 $CE-$CF Pointer for Kern a 1 PR1MM routine 739-763 $02E3-$02FB Jumps to a routine in any bank
208 $D0 Number of characters in the keyboard buffer 764-765 $02FC-$02FD Indirect vector for extended functions
209 $D1 Number of characters pending from programmable 766-767 $02FE-$02FF Unused indirect vector
key string 768-769 $0300-$0301 Indirect vector in BASIC ERROR routine
210 $D2 Pointer into the programmable key definition area 770-771 $0302-$0303 Indirect vector in BASIC MAIN routine
211 $D3 Shift key status flag 772-773 $0304-$0305 Indirect vector in BASIC CRUNCH routine
212 $D4 Current key pressed (matrix value) 774-775 $0306-$030; Indirect vector in BASIC QPLOP routine
213 $D5 Last key pressed 776-777 $0308-$0309 Indirect vector in BASIC GONE routine
214 $D6 Input source flag 778-779 $030A-$030B Indirect vector in BASIC EVAL routine
215 $D7 Active screen flag 780-781 $030C-$030D Indirect vector for tokenizing new keywords
216 $D8 Mode flag for 40-column screen 782-783 $030E-$030F Indirect vector for listing new keywords
217 $D9 CHAREN bit shadow 784-785 $0310-$0311 Indirect vector for executing new statements
218-223 SDA-$DF 5creen editor zero page work area 786-787 $0312-$0313 Unused
224-225 $EO-$E1 Pointer to first screen memory location for current 788-789 $0314-$0315 Indirect vector to IRQ handling routine
line 790-791 $0316-$0317 Indirect vector to BRK handling routine
226-227 $E2-$E3 Pointer to first attribute memory location for current 792-793 $0318-$0319 Indirect vector to NMI handling routine
line 794-795 $031A-$031B Indirect vector in Kernal OPEN routine
228 $E4 Bottom margin of current window 796-797 $031C-$031D Indirect vector in Kemal CLOSE routine
229 $E5 Top margin of current window 798-799 S031E-S031F Indirect vector in Kemal CHKIN routine
230 $E6 Left margin of current window 800-801 $0320-$0321 Indirect vector in Kernal CKOUT routine
231 $E7 Right margin of current window 802-803 $0322-$0323 Indirect vector in Kernal CLRCH routine
232 $E8 Cursor row for start of input 804-S05 $0324-$0325 Indirect vector in Kemal BASIN routine
233 $E9 Cursor column for start of input 806-807 $0326-$0327 Indirect vector in Kemal BSOUT routine
234 $EA Column of last nonspace character on logical line 808-809 $0328-$0329 Indirect vector in Kernal STOP routine
235 $EB Cursor row 810-811 $032A-$032B Indirect vector in Kemal GETIN routine
236 $EC Position of cursor within current logical line 812-813 $032C-$032D Indirect vector in Kemal CLALL routine
237 $ED Maximum number of rows allowed in output window 814-815 $032E-$032F Indirect vector in monitor EXMON routine
238 SEE Maximum number of columns allowed per row 816-817 $0330-$0331 Indirect vector in Kernal LOAD routine
239 SEF Character to print 818-819 $0332-$0333 Indirect vector in Kemal SAVE routine
240 $F0 Last character printed 820-821 $0334-$0335 Screen editor indirect vector
241 $F1 Attribute of current character 822-823 $0336-$O337 Screen editor indirect vector
242 $F2 Temporary storage for attribute byte 824-825 $0338-$0339 Screen editor indirect vector
243 $F3 Reverse mode flag 826-827 $033A-$033B Screen editor indirect vector
244 $F4 Quote mode flag 828-829 $033C-$033D Screen editor indirect vector
245 $F5 Number of pending inserts 830-841 $033E-$0349 Screen editor indirect vector
246 $F6 Autoinsert mode flag 842-851 $034A-$0353 Keyboard buffer
247 $F7 Case switching/scroll pause control flag 852-861 $0354-$035D Tab stop bitmap
248 $F8 Scroll/link control flag 862-865 $035E-$0361 Line link bitmap
249 $F9 Bell enable flag 866-875 $0362-$036B Logical file number table for currently open files
250 $FA Unused 876-885 $036C-$0375 Device number table for currently open files
251-254 tFB-SFE Unused 886-895 $0376-$037F Secondary address table for currently open files
255-266 $OOFF-$010A Assembly area for numeric strings 896-926 $0380-$039E CHRGET (main BASIC character retrieval routine)
256-511 $0100-$0IFF Processor stack area 927-977 $O39F-$O3D1 Alternate BASIC character retrieval subroutines
256-268 $0100-$010C Assembly area for disk boot command 978-980 $03D2-$03D4 Null descriptor
256-317 $0100-$013D Tape error log 981 $03D5 Bank number for PEEK and POKE
272-290 $0110-$0122 DOS command work area 982-985 $03D6-$3D9 Pointers for INSTR evaluation
291-310 S0I23-S0136 PRINT USING work area 986 $03DA String block flag
294 $0126 Command type indicator for PLAY processing 987-990 $03DB-$03DE Temporary storage for SHAPE data
666 667
/
991 $03DF Floating-point overflow byte 2611 S0A33 Attribute of current cursor position
992-993 $03E0-$03El Temporary pointer storage 2612 $0A34 Scan line for screen split
994 $03E2 Standard bitmap color fill value 2613 $0A35 Temporary storage for X register
995 $03E3 Multicolor bitmap color fill value 2614 $0A36 Jiffy clock compensation flag
996-1007 $03E4-$03EF Unused 2615 $0A37 Temporary storage for clock rate register
1008-1020 $03FO-$03FC DMA—CALL execution routine 2616 $0A38 Temporary storage for sprite enable register
1021-1023 $03FD-$03FF Unused 2617 $0A39 Temporary storage for VIC control register
2618 $0A3A Custom mode flag
Chapter 3: Bank 0 Working Storage 2619
2620-2621
$0A38
$0A3C-$0A3D
Starting page for 40-coiumn screen memory
Working pointer into 80-column memory
1024-2023 $0400-07FF Default VIC screen memory 2622-2623 $0A3E-$0A3F Unused
2024-2559 $0800-$09FF BASIC runtime stack 2624-2650 $0A40-$0A5A Screen editor variable storage for the inactive screen
2560-2561 $OA00-$0AOl BASIC restart vector 2651-2655 $0A5B-$0A5F Unused
2562 $OA02 Memory initialization status flag 2656-2665 $0A60-$0A69 Storage for inactive tab stop bitmap
2563 $0A03 PAL/NTSC flag 2666-2669 $0A6A-$0A6D Storage for inactive line link bitmap
2564 $0A04 System initialization status flag 2670-2687 $0A6E-$0A7F Unused
2565-2566 $0A05-$OA06 Kernal MEMBOT pointer 2688-2703 $OA80-$OA8F Filename buffer for load, save, or verify
2567-2568 $0AO7-$0A08 Kemal MEMTOP pointer 2688-2719 $0A80-$0A9F Search pattern buffer
2569-2570 $OA09-$OAOA Temporary storage for ILRQ vector during tape 2720-2727 $0AA0-$0AA7 Working storage for base conversion
operations 2720-2729 $0AA0-$0AA9 Instruction assembly buffer
2571 $OA0B CIA #1 control register A log 2730 $0AAA Instruction format flag
2572 $OA0C CIA #1 interrupt control register log 2731 $0AAB Instruction length
2573 $OA0D CIA #1 timer A status log 2732-2734 $OAAC-$0AAE Three-character mnemonic pattern
2574 $0A0E IEEE timeout flag 2735 $0AAF Temporary storage for X register
2575 $0A0F RS-232 activity flag 2736 $OAB0 Unused
2576 $OA10 RS-232 control register 2737 $0ABl Calculated opcode
2577 S0A11 RS-232 command register 2738 $0AB2 Temporary storage for X register
2578-2579 $0A12-$0A13 RS-232 baud rate factor 2739 $0AB3 Transfer direction flag
2580 S0A14 RS-232 status register 2740 $0AB4 Digit counter
2581 $0A15 RS-232 bit count 2741 $0AB5 Temporary storage for parameter conversion
2582-2583 $OA16-$0A17 R5-232 baud rate timing constant 2742 $0AB6 Number of bits per digit for base
2584 $0A18 Index to firs! character in RS-232 input buffer 2743-2745 $0AB7-$0A39 Monitor temporary storage
2585 $0A19 Index to last character in RS-232 input buffer 2746-2751 $OABA-$0ABF Unused
2586 $OA1A Index to first character in RS-232 output buffer 2752 $0AC0 Counter for function ROM testing
2587 $OA1B Index to last character in RS-232 output buffer 2753-2756 $0ACl-$0AC4 Table of identifiers for function ROMs
2588 J0A1C Fast serial mode flag 2757 $0AC5 DK_FLAG
2589-2591 $OA1D-$OA1F Software jiffy timer 2758-2815 S0AC6-$0AFF Unused
2592 $0A20 Maximum number of keys in the keyboard buffer 2816-307] $OBO0-$0BFF Cassette buffer/disk boot buffer
2593 $0A21 Scroll pause flag 3072-3327 S0C00-SOCFF RS-232 input buffer
2594 $0A22 Key repeat flag 3328-3583 $0DO0-$0DFF RS-232 output buffer
2595 $0A23 Countdown between key repeats 3584-4095 $0E00-$OFFF Sprite pattern storage area
2596 $0A24 Countdown until key repeating begins 4096-4351 $1000-$lFFF Programmable key definition storage area
2597 $0A25 Delay between case switching repeats 4352-4400 $1100-$1130 DOS command assembly area
2598 $0A26 Cursor blink flag 4401-4402 $1131-$1132 Bitmapped screen pixel cursor horizontal position
2599 $0A27 Cursor enable flag 4403-4404 $1133-$1134 Bitmapped screen pixel cursor vertical position
2600 $0A28 Cursor blink countdown 4405-4406 $1135-$U36 Final horizontal pixel position for graphics operations
2601 $0A29 Character under cursor 4407-4408 $1137-$1138 Final vertical pixel position for graphics operations
2602 $0A2A Color under cursor 4409-4455 $1139-$1177 Working storage for assorted graphics routines
2603 $0A2B VDC cursor mode 4456 $1168 Starting page for character pattern definitions
2604 S0A2C VIC text screen and character base 4457 $1169 Bit counter for shape retrieval
2605 $0A2D VIC bitmap and video matrix base 4458 $116A Scaling flag
2606 $0A2E Starting page for VDC screen memory 4459 $116B Line width for bitmapped graphics routines
2607 $0A2F Starting page for VDC attribute memory 4460 $116C BOX fill flag
2608 $0A3O Ending row for screen input 4461 $116D Bit mask value
2609-2610 $0A31-$OA32 Temporary storage for 80-column memory 4462 $116E Temporary storage for assorted routines
manipulation 4463 $116F Trace mode flag
668 669
4464-4467 $1170-$1173 Working storage for RENUMBER 4729-4734 $1279-$127D Target line numbers for COLLISION
4468 $1174 Loop counter for reading directory entries 4735 $127F Collision enable flag
4469-4470 $1175-$1176 Block count for directory entry 4736 $1280 Collision type index
4471 $1177 Working storage for graphics parameter scaling 4737 $1281 Voice for current SOUND statement
4472 $1178 Working storage for graphics parameter evaluation 4738-4770 S1282-S12A2 Table of SOUND statement settings
4473 $1179 Working storage for graphics parameter evaluation 4771-4776 $12A3-$12A8 Parameters for most recent SOUND statement
4474-4475 $117A-$117B Pointer to floating point-to-integer conversion routine 4785 $12B1 Temporary storage for POT and PEN routines
4476-4477 $117C-$117D Pointer to integer-to-floating poinl conversion routine 4786 $12B2 Temporary storage for POT routine
4478-4565 $117E-S11D5 Sprite movement control data 4787-4790 $12B3-$12B6 Temporary parameter storage for WINDOW
4566-4582 $11D6-$1IE6 Shadows for VIC sprite position registers statement
4583-4584 $11E7-$1IE8 Shadows for VIC sprite collision registers 4791-4806 $12B7-$12C6 Filename buffer for DOS support commands
4585-4586 $11E9-$11EA Shadow for VIC light pen registers 4791-4854 $12B7~$12F6 Sprite pattern storage
4587 $11EB Starting page for alternate character set during CHAK 4854-4857 $12F6-$12F9 Sprite pattern suffix
4588 $11EC Starting page for default character set during CHAR 4858 S12FA Sprite mode indicator for SPRDEF
4589 $11ED Channel number for BASIC relative file operations 4859 $12FB Sprite pattern line count for SPRDEF
4590-4607 $11EE-$11FT Unused 4860 $12FC Sprite number for SPRDEF
4608-4609 $1200-$1201 line number where program stopped 4861 $12PD BASIC IRQ activity flag
4610-4611 $1202-$1203 Pointer to the start of current line 4862-4863 $12FE-$12FF Unused
4612-4615 $1204-$!207 Character definitions for PRINT USING
4616 $1208 Number of most recent error
4617-4618 $1209-$120A Line number where most recent error occurred Chaptei 5: BASIC
4619-4620 $120B-$120C Target line number for TRAP statement 16384 $4000 BASIC cold-start entry point
4621 $120D Temporary storage for high byte of TRAP line 16387 $4003 BASIC warm-start entry point
number 16390 $4006 BASIC IRQ entry point
4622-4623 $120E-$120F Pointer to start of statement where last error occurred 16393 $4009 Performs a warm start of BASIC
4624-4625 $1210-$1211 End-of-program pointer 16416 $4020 Unused
4626-4627 $1212-$1213 Top-of-BASIC pointer 16419 $4023 Performs a cold start of BASIC
4628-4629 $1214-$1215 Temporary text pointer storage for DO 16453 $4045 Initializes BASIC pointers and constants
4630-4631 $1216-$1217 Temporary line number storage for DO 16658 $4112 Initializes SID registers and sound routine locations
4632-4634 $1218-$121A USR function jump vector 16762 $417A Initializes MMU preconfiguration registers
4635-4639 $121B-$121F Seed value for random number generation 16781 $418D Initializes sprite speed and direction table
4640 $1220 Degrees between segments for CIRCLE routine 16795 $419B Displays the power-on message
4641 $1221 Unused 16827 $41BB Text for power-on message
4642 $1222 Tempo setting for PLAY statement 16977 $4251 Initializes BASIC indirect vectors
4643-4648 S1223-$1228 Durations for currently active notes 16999 $4267 Table of default vector values
4649-4650 $1229-$122A Duration of current note 17017 $4279 Text for character retrieval routines
4651 S122B Octave for current note 17102 $42CE Assorted character retrieval subroutines
4652 $122C Sharp/flat flag 17162 $430A Tokenizes keywords in lines of BASIC program text
4653-4654 $122D-$122E Frequency for current note 17328 S43B0 Handles extended tokens
4655 $122F Voice number for current note 17356 $43CC Deletes a character in the input buffer
4656-4658 $1230-$1232 Waveforms for current notes 17378 $43E2 Searches keyword tables for match
4659 $1233 Dotted note flag 17431 $4417 BASIC keyword tables
4660-4661 $1234-$1235 Current filter cutoff frequency 17929 $4609 Table of extended token statements
4662 $1236 Current resonance setting 18121 $46C9 Table of extended token functions
4663 $1237 Current filter type 18172 $46FC Table of statement dispatch addresses
4664 $1238 Filter type index 18242 $4742 Table of statement dispatch addresses
4665 $1239 Temporary storage 18172 $46FC Table of statement dispatch addresses
4666 $123A Current instrument number 18317 $478D Table of function dispatch addresses
4667-4669 $123B-$123D Envelope parameters for current instrument 18454 $4816 Table of function dispatch addresses
4670 $123E Index into instrument table for current instrument 18472 $4828 Table of operator priorities and dispatch addresses
4671-4720 $123F-$1270 Instrument parameter tables 18502 $4846 Prints unimplemented command message
4721-4722 $1271-$1272 Current filter cutoff frequency 18507 $484B Table of BASIC error messages
4723 $1273 Current filter control and resonance setting 19074 $4A82 Sets pointer to error message
4724 $1274 Current filter type selection 19103 $4A9F Main BASIC statement execution routine
4725 $1275 Current SID chip volume setting 19190 $4AF6 Executes the next BA5IC statement
4726-4728 $1276-$!278 Collision flags 19381 S4BB5 Tests for RUN/STOP keypress
670 671
19403 $4BCB Handles the STOP and END statements 23069 $5A1D Places RETURN parameters in the runtime stack
19447 $4BF7 Handles the execution of function keywords 23101 S5A3D Handles the GO statement
19587 $4C83 Displays the SYNTAX ERROR message 23136 $5A60 Handles the CONT statement
19590 $4C86 Handles the OR logical operator 23169 $5A81 Sets flags for running a program
19593 $4C89 Handles the AND logical operator 23195 $5A9B Handles the RUN statement
19638 $4CB6 Handles relational operators (<, —, >) 23242 $5ACA Handles the RESTORE statement
19754 $4D2A Prints the READY prompt 23280 $5AF0 Table of tokens for RENUMBER
19767 $4D37 Enters MAIN with a READY prompt 23288 $5AF8 Handles the RENUMBER statement
19770 $4D3A Displays an OUT OF MEMORY error message 24057 $5DF9 Handles the FOR statement
19772 $4D3C Handles BASIC errors 24199 S5ES7 Handles the DELETE statement
19836 $4D7C Prints a specified error message 24372 $5F34 Handles the PUDEF statement
19895 $4DB7 Handles immediate mode and program line entry 24397 $5F4D Handles the TRAP statement
19938 $4DE2 Adds or deletes BASIC program lines 24418 $5F62 Handles the RESUME statement
20303 $4F4F Relinks BASIC program lines 24544 $5FE0 Handles the DO statement
20371 S4F93 Reads a line of input into the buffer 24633 $6039 Handles the EXIT statement
20394 $4FAA Searches for a particular token in the runtime stack 24714 $608A Handles the LOOP statement
20478 $4FFE Decrements the runtime stack pointer 24801 $6OE1 Assigns a definition string to a programmable key
20503 $5017 Checks for available string space 24842 $610A Handles the KEY statement
20569 $5059 Increments runtime stack pointer 24989 $619D Table of characters for KEY
20580 $5064 Searches program text for a specified line number 25000 $61A8 Handles the PAINT statement
20640 $50AO Creates integer value from a character string 25271 $62B7 Handles the BOX statement
20706 $50E2 Handles the LIST statement 25643 $642B Handles the SSHAPE statement
20771 $5123 Lists a single BASIC program line 25997 $65 8D Handles the GSHAPE statement
20950 $51D6 Handles the NEW statement 26254 $668E Handles the CIRCLE statement
20984 $51F8 Handles the CLR statement 26443 $6750 Bitmapped graphics circle drawing subroutine
21076 $5254 Resets the CHRGET text pointer 26519 $6797 Handles the DRAW statement
21090 $5262 Handles the RETURN statement 26583 $67D7 Handles the CHAE statement
21135 $528F Handles the BEND and DATA statements 26965 $6955 Handles the LOCATE statement
21149 $529D Handles the REM statement 26976 $6960 Handles the SCALE statement
21189 $52C5 Handles the IF statement 27096 $69D8 Table of scaling factors
21280 $5320 Skips a BEGIN-BEND block 27106 $69E2 Handles the COLOR statement
21393 $5391 Handles the ELSE statement 27212 $6A4C Table for translating VIC color values to VDC color
21411 $53A3 Handles the ON statement values
21446 $53C6 Handles variable value assignments 27228 $6A5C Calculates color fill values
21818 $553A Handles the PRINT* statement 27257 $6A79 Handles the SCNCLR statement
21824 $5540 Handles the CMD statement 27482 $6B5A Handles the GRAPHIC statement
21844 $5554 Handles the PRINT statement 27593 $6BC9 Handles the BANK statement
22034 $5612 Handles the GET statement (also GET# and 27607 $6BD7 Handles the SLEEP statement
GETKEY) 27693 $6C2D Handles the WAIT statement
22088 $5648 Handles the ENPUT# statement 27727 $6C4F Handles the SPRITE statement
22114 $5662 Handles the INPUT statement 27846 $6CC6 Handles the MOVSPR statement
22185 $56A9 Handles the READ statement 28129 $6DE1 Handles the PLAY statement
22474 $57CA Moves the CHRGET text pointer to the next DATA 28631 $6FD7 Handles the TEMPO statement
statement 28644 $6FE4 Data tables for PLAY string processing
22516 $57F4 Handles the NEXT statement 28689 $7011 Default values for ENVELOPE instrument tables
22648 $5878 Handles the DIM statement 28742 $7046 Handles the FILTER statement
22661 $5885 Handles the SYS statement 28865 $70Cl Handles the ENVELOPE statement
22708 $58B4 Handles the TRON and TROFF statements 29028 $7164 Handles the COLLISION statement
22717 $58BD Handles the RREG statement 29072 $7190 Handles the SPRCOLOR statement
22785 $5901 Handles MID$ when used as a statement 29110 $71B6 Handles the WIDTH statement
22901 $5975 Handles the AUTO statement 29125 $71C5 Handles the VOL statement
22918 $5986 Handles the HELP statement 29164 $71EC Handles the SOUND statement
22956 $59AC Highlights the portion of a listed line containing an 29388 $72CC Handles the WINDOW statement
error 29493 $7335 Handles the BOOT statement
2299] $59CF Handles the GOSUB statement 29554 $7372 Handles the SPRDEF statement
23003 $59DB Handles the GOTO statement 30444 $76EC Handles the SPRSAV statement
673
30643 $77B3 Handles the FAST statement 34862 $882E Subtracts value in memory from FAC1
30660 $77C4 Handles the SLOW statement 34865 $8831 Subtracts FAC1 from FAC2
30679 $77D7 Evaluates an expression with a test for type mismatch 34885 $8845 Adds value in memory to FAC1
30703 $77EF Evaluates an expression 34888 $8848 Adds FAC1 to FAC2
30935 $78D7 Evaluates a single term of a numeric expression 34993 $88B1 Normalizes FAC1
31084 $796C Displays a SYNTAX ERROR message 35110 $8926 Forms twos complement of FAC1
31096 $7978 Evaluates a variable value 35165 $895D Displays OVERFLOW error message
31407 $7AAF Finds or creates a variable 35170 $8962 Performs byte alignment of FAC1
31632 $7B90 Creates an entry in the variable table for a new scalar 35274 $89CA Handles the LOG function
variable 35342 $8A0E Adds 0.5 to FAC1
31846 $7C66 Moves arrays upward in bank 1 to make room for a 35364 $8A24 Multiplies value in memory by FAC1
new scalar variable 35367 $8A27 Multiplies value in memory by FAC1
31915 $7CAB Finds or creates an array variable 35465 $8A89 Loads FAC2 with value from the current bank
32768 $8000 Handles the FRE function 35508 $8AB4 Loads FAC2 with value from bank 1
32800 $8020 Prints designers message 35607 $8B17 Multiplies FAC1 by 10
32842 $804A Handles the VAL function 35640 $8B38 Divides FAC1 by 10
32886 $8076 Handles the DEC function 35657 $8B49 Divides value in memory by FAC1
32965 $80C5 Handles the PEEK function 35660 $8B4C Divides FAC2 by FAC1
32997 $80E5 Handles the POKE statement 35796 $8BD4 Loads FAC1 from memory
33014 $80F6 Handles the ERR$ function 35840 $8C00 Copies FAC1 value into memory
33090 $8142 Handles the HEX$ function 35880 $8C28 Copies FAC2 into FAC1
33154 $8182 Handles the RGR function 35896 $8C38 Copies FAC1 into FAC2
33179 $819B Handles the RCLR function 35911 $8C47 Rounds FAC1
332S3 $8203 Handles the JOY function 35927 $8C57 Determines the sign of the value in FAC1
33357 $824D Handles the POT function 35941 $8C65 Handles the SGN function
33454 $82AE Handles the PEN function 35972 $8C84 Handles the AB5 function
33530 $82FA Handles the POINTER function 35975 $8C87 Compares FAC1 against FAC2
33566 $831E Handles the RSPR1TE function 36039 $8CC7 Converts FAC1 to a four-byte integer
33633 $8361 Handles the RSPCOLOR function 36091 $8CFB Handles the INT function
33660 $837C Handles the BUMP function 36120 $8D18 Fills FAC1 with the value in the accumulator
33687 $8397 Handles the RSPPOS function 36130 $8D22 Generates floating point value representing character
33761 $83E1 Handles the XOR function string
33799 $8407 Handles the RW1ND0W function 36390 $8E26 Prints IN and a line number
33844 $8434 Handles the RND function 36398 $8E2E Prints a line number
33936 $8490 Table of floating point constants for RND calculation 36418 $8E42 Generates a character string representing the value in
34000 $84D0 Handles the POS function FAC1
34009 $84D9 Checks that BASIC is in run mode 36791 $8FB7 Handles the SQR function
34032 $84F0 Checks that BASIC is in immediate mode 36801 $8FC1 Handles the exponentiation (T) operator
34042 $84FA Handles the DEF statement 36869 $9005 Table of floating point constants for EXP evaluation
34107 $853B Handles user-defined functions using FN 36915 $9033 Handles the EXP function
34222 $85AE Handles the STR$ fucntion 36998 $9086 Performs series evaluation
34239 $85BF Handles the CHR$ function 370B0 $90D8 Calls the Kernal OPEN routine
34262 $85D6 Handles the LEFT$ function 37087 $90DF Calls the Kernal BSOUT routine
34314 $860A Handles the RIGHT$ function 37093 $90E5 Calls the Kernal BASIN routine
34332 $861C Handles the MTD$ function 37117 $90FD Calls the Kemal CHKIN routine
34408 $8668 Handles the LEN function 37129 $9109 Calls the Kemal GETIN routine
34423 $8677 Handles the ASC function 37138 $9112 Handles the SAVE statement
34437 $8685 Displays the ILLEGAL QUANTITY error message 37161 $9129 Handles the VERIFY statement
34440 $8688 Creates space for a string in the string pool 37164 $912C Handles the LOAD statement
34458 $869A Stores a string in the string pool 37261 $918D Handles the OPEN statement
34573 $870D Performs string concatenation 37274 $919A Handles the CLOSE statement
34683 $877B Evaluates a string parameter 37294 $91AE Evaluates parameters for SAVE, LOAD, and VERIFY
34801 $87F1 Evaluates a numeric expression 37366 $91F6 Evaluates parameters for OPEN and CLOSE
34819 $8803 Evaluates parameters for POKE or WAIT 37433 $9239 Clears DS$ after disk operations
34831 $880F Checks that the next character is a comma 37457 $9251 BASIC calls to Kemal routines
34837 $8815 Evaluates a numeric parameter 37457 $9251 BASIC call to Kernal's READSS routine
674
i 675
37463 $9257 BASIC call to Kemal's 5ETLFS routine 42872 $A778 Reads disk status string (DS$)
37469 $925D BASIC call to Kernal's SETNAM routine 42977 $A7E1 Provides AKE YOU SURF, query
37475 $9263 BASIC call to Kemal's BASIN routine 43021 $A80D Clears disk status string
37481 $9269 BASIC call to Kemal's BSOUT routine 43077 $A845 Switches to bank 15 configuration
37487 $926F 3ASIC call to Kemal's CLRCH routine 43085 $A84D BASIC IRQ service routine
37493 $9275 BASIC call to Kemal's CLOSE routine 43504 $A9F0 Common exit point from BASIC IRQ routine
37499 $927B BASIC call to Kemal's CLALL routine 43551 $AA1F Handles the STASH statement
37505 $9281 BASIC call to Kemal's PRIMM routine 43556 $AA24 Handles the FETCH statement
37511 $9287 BASIC call to Kemal's SETBANK routine 43561 $AA29 Handles the SWAP statement
37517 $928D BASIC call to Kemal's PLOT routine 43630-44642 $AA6E-$AE62 Unused
37523 $9293 BASIC call to Kemal's STOP routine 44643-44799 $AE63-$AEFF Encoded message from the designers of the 128
37529 $9299 Creates space in the string pool for a temporary string 44800 $AF00 Entry point for the AYINT routine
37610 $92EA Performs garbage collection on string pool 44803 $AF03 Entry point for the GIVAYF routine
37897 $9409 Handles the COS function 44806 $AF06 Entry point for the FOUT routine
37904 $9410 Handles the SIN function 44809 $AF09 Entry point for the VA1 1 routine
37977 $9459 Handles the TAN function 44812 $AF0C Entry point for the GETADR routine
38021 $9485 Table of constants for trig function evaluation 44815 $AF0F Entry point for the FLOATC routine
38067 $94B3 Handles the ATN function 44818 $AF12 Entry point for the FSUB routine
38115 $94E3 Table of constants for trig function evaluation 44821 $AF15 Entry point for the FSUBT routine
38176 $9520 Handles the PRINT USING statement 44824 $AF18 Entry point for the FADD routine
39361 $99C1 Handles the INSTR function 44827 $AF1B Entry point for the FADDT routine
39692 $9B0C Handles the RDOT function 44830 $AF1E Entry point for the FMULT routine
39728 $9B30 Bitmapped graphics line drawing routine 44833 $AF21 Entry point for the FMULTT routine
39931 $9BFB Bitmapped point plotting routine 44836 $AF24 Entry point for the FDIV routine
40010 $9C4A Scales graphics parameter 44839 $AF27 Entry point for the FDIVT routine
40366 $9DAE Applies scaling factor to a specified parameter 44842 $AF2A Entry point for the LOG routine
40557 $9E6D Evaluates graphics parameters 44845 $AF2D Entry point for the INT routine
40712 $9F08 Handles relative graphics parameters 44848 $AF30 Entry point for the SQR routine
40783 $9F4F Allocates the bitmapped graphics area 44851 $AF33 Entry point for the NEGOP routine
40903 $9FC7 Adjusts BASIC program pointers for graphics area 44854 $AF36 Entry point for the FPVVR routine
allocation or de-allocation 44857 $AF39 Entry point for the FPWRT routine
40994 $A022 De-allocates the bitmapped graphics area 44860 $AF3C Entry point for the EXP routine
41076 $A074 44863 $AF3F Entry point for the COS routine
Confirms that the graphics area has been allocated Entry point for the SIN routine
41086 $A07E Handles the CATALOG and DIRECTORY statements 44866 $AF42
44869 $AF45 Entry point for the TAN routine
41245 $A11D Handles the DOPEN statement Entry point for the ATN routine
41268 $A134 Handles the APPEND statement 44872 $AF48
44875 $AF4B Entry point for the ROUND routine
41303 $A157 Finds an available secondary address Entry point for the ABS routine
43327 $A16F Handles the DCLOSE statement 44878 $AF4E
44881 $AF51 Entry point for the SIGN routine
41347 $A183 Closes all open files for a specified device Entry point for the FCOMP routine
41356 $A18C Handles the DSAVE statement 44884 $AF54
44887 $AF57 Entry point for the RND_0 routine
41380 $A1A4 Handles the DVERIFY statement Entry point for the CONUPK routine
41383 $A1A7 Handles the DLOAD statement 44890 $AF5A
44893 JAF5D Entry point for the ROMUPK routine
41416 $A1C8 Handles the BSAVE statement Entry point for the MOVFRM routine
41496 $A218 Handles the BLOAD statement 44896 $AF60
44899 $AF63 Entry point for the MOVFM routine
41575 $A267 Handles the HEADER statement Entry point for the MOVMF routine
41633 $A2A1 Handles the SCRATCH statement 44902 $AF66
44905 $AF69 Entry point for the MOVFA routine
41687 $A2D7 Handles the RECORD statement Entry point for the MOVAF routine
41762 $A322 Handles the DCLEAR statement 44908 $AF6C
44914 $AF72 Entry point for the DRAWLN rotuine
41775 SA32F Handles the COLLECT statement Entry point for the GPLOT routine
41798 $A346 Handles the COPY statement 44917 SAF75
44920 $AF78 Entry point for the CIRSUB routine
41826 $A362 Handles the CONCAT statement Entry point for the RUN routine
41838 $A36E Handles the RENAME statement 44923 $AF7B
44926 $AF7E Entry point for the RUNC routine
41852 $A37C Handles the BACKUP statement Entry point for the CLR routine
41923 $A3C3 Evaluates parameters for disk commands 44929 $AF81 Entry point for the NEW routine
42535 $A627 Table of disk command templates 44932 $AF84
Entry point for the LNKFRG routine
42599 $A667 Sets up disk command buffer 44935 $AF87
676 677
44938 SAFSA Entry point for the CRUNCH routine
47284 $B8B4 Moves cursor to start of next line
44941 $AF8D Entry point for the FNDLN routine 47289 $B8B9 Clears a screen line
44944 $AP90 Entry point for the NEWSTT routine 47298 SB8C2 Prints two ASCII characters for a byte value
44947 $AF93 Entry point for the EVAL routine
44950 $AF96 47314 JB8D2 Converts a byte value into two ASCII characters
Entry point for the FRMEVL routine
44953 $AF99 47335 $B8E7 Tests next character in the input buffer
Entry poinl for the RUN routine
44956 $AF9C 47361 $B901 Transfers address and bank values to working pointer
Entry point for the SETEXC routine
44959 $AF9F 47374 $B90E Calculates number of bytes and banks to display or
Entry point for the LINGET routine
44962 $AFAZ Entry move
point for the GARBA2 routine
44965 $AFA5 Entry 47394 $B922 Decrements address or line count
point for the MAIN routine
47420 $B93C Decrements byte count
47440 $B950 Increments address pointer
47456 SB960 Decrements address pointer
Chapter 6: Machine Language Monitor ROM 47476 $B974 Changes bank and address
45056 $B0OO Monitor cold start entry point 47491 $B983 Prepares pointers for dual-address operations
45059 $B003 Monitor break entry point 47537 SB9B1 Performs number base conversion
45062 $B006 Reentry point from the IMON indirect vector 47623 $BA07 Converts a hexadecimal value to decimal
45065 $B009 Monitor entry routine when BRK instruction 47687 $BA47 Prints octal, binary, or decimal values
encountered 47760 $BA90 Handles @ (disk) commands
45089 $B021 Cold start routine for monitor 47875 $BB03 Displays disk directory
45136 $B050 Handles R (register display) command 47986-49151 $BB72-$BFFF Unused
45195 $B08B Main command execution loop for the monitor
45285 $B0E3 Handles X (exit to BASIC) command
45288 $B0E6 Table of monitor commands Chapter 7: Screei Editor ROM
45308 SB0FC Table of execution addresses for the monitor
commands
49152
49263
$cooo
$C06F
Screen editor jump table
Table of default keyboard decoding table pointers
45338 $B11A INDFET call for the monitor 49275 $C07B Initializes screen editor constants, variables, tables,
45354 $B12A INDSTA call for the monitor and vectors
45373 SB13D INDCMP call for the monitor 49474 $C142 Clears the current window and homes the cursor
45394 $B152 Handles M (memory display) command 49488 $C150 Moves the cursor to the home position of the current
45460 $B194 Handles ; (change register) command window
45483 $B1AB Handles > (change memory) command 49500 $C15C Sets starting address pointers for the current line
45526 $B1D6 Handles G (go to routine) command 49502 $C15E Sets starting address pointers for a specified line
45535 $B1DF Handles ] (jump to subroutine) command 49556 $C194 Performs screen and keyboard portion of IRQ
45544 $B1E8 Displays a line of memory as hex bytes and ASCII functions
characters 49716 $C234 Performs GETIN from keyboard
45617 $B23I Compares or transfers blocks of memory 49752 $C258 Accepts a line of keyboard input and returns the first
45774 $B2CE Searches memory for byte pattern character
45879 $B337 Prepares for save, load, or verify 49819 $C29B Performs BASIN from screen or keyboard
45983 $B39F Handles save for monitor 49919 $C2FF Handles quote mode flag
45995 $B3AB Handles load and verify 49932 $C30C Provides common exit for screen BSOUT subroutines
46033 $B3D1 Prepares for relocating load or verify 49952 $C320 Handles character printing for screen BSOUT
46043 $B3DB Fills memory with specified byte value 49982 SC33E Updates the cursor position
46086 $B406 Handles A (assemble) command, or its equivalent 50019 $C363 Moves the cursor down one line
46489 $B599 Handles D (disassemble) command 50044 $C37C Inserts a new line linked to the one above
46548 SB5D4 Disassembles a single instruction 50086 $C3A6 Scrolls the window up one line
46681 $B659 Calculates mnemonic and addressing mode 50140 $C3DC Copies lines up one row and clears bottom line
46753 $B6A1 Prints mnemonic for opcode 50189 $C40D Copies a line
46787 $B6C3 Opcode decoding table 50341 $C4A5 Clears a line
46855 $B707 Table of addressing mode indicators 50492 $C53C Fills or copies a block of 8563 RAM
46869 $B715 Scans keyboard matrix for keypress
Table of mode identification characters 50525 $C55D
468S1 $B721 Decodes key matrix value into character value and
Table of mnemonics in packed form 50769 SC651
47013 $B7A5 handles key repeating
Evaluates a parameter in the input buffer
47054 SB7CE Table of programmable key character values
Transforms numeric parameter into byte value 50909 $C6DD
47242 $BS8A Handles cursor blinking for 40-column screen
Table of bases and bits-per-digit 50919 $C6E7
47250 $B892 Prints a hexadecimal value 50989 $C72D Handles BSOUT to the screen
47277 $B8AD Moves cursor to start of current line 51055 $C76F Handles RETURN and SHIFT-RETURN characters,
CHR$(13) and CHR$(141)
678 679
51069 SC77D Cancel quote arid reverse modes and dear pending
inserts (ESC O and ESC ESC) 52023 $CB37 Enables tone for bell character (ESC G)
51084 $C78C Tables of screen control codes and dispatch addresses 52026 $CB3A Disables tone for bell character (ESC H)
51126 $C7B6 Interprets character codes less than 32 52031 $CB3F Switches 80-column screen to reverse mode (ESC R}
51162 $C7DA Handles color change characters 52040 SCB48 Switches 80-column screen to normal mode (ESC N)
51190 $C7F6 Calls control code execution routines 52050 $CB52 Moves the cursor past the last character on the cur-
51202 $C802 Interprets character codes greater than 127 rent logical line (ESC K)
51220 $C814 Handles character codes 128-159 52056 $CB58 Reads character and attribute at current cursor
51284 $C854 Handles cursor right character, CHR$(29) position
51290 $C85A Handles cursor down character, CHR$(17) 52084 $CB74 Tests whether a line is linked
51293 $C85D Checks whether cursor moved onto a new logical line 52097 $CB81 Links or unlinks the current screen line
51303 $C867 Handles cursor up character, CHR$(145) 52101 $CB85 Unlinks a screen line
51317 $C875 Handles cursor left character, CHR$(157) 52115 $CB93 Links a screen line
51328 $C880 Handles switch-to-lowercase character, CHR$(14) 52127 $CB9F Calculates offsets into the line link bitmap
51346 $C892 Handles switch-to-uppercase character, CHR${142) 52145 $CBB1 Moves the cursor to the start of logical line (ESC J)
51366 $C8A6 Handles case switching disable character, CHR$(11) 52163 $CBC3 Finds the position of the last character in a line
51372 $C8AC Handles case switching enable character, CHR$(12) 52205 SCBED Moves the cursor one position to the right
51379 $C8B3 Handles cursor home character, CHR$(19) 52224 $CC00 Moves the cursor one position to the left
51391 $C8BF Handles reverse off character, CHE${146) 52254 $CC1E Stores the cursor position for later restoration
51394 $C8C2 Handles reverse on character, CHR$(18) 52263 $CC27 Prints a space
51399 $C8C7 Handles underline on character, CHR$(2) 52271 $CC2F Displays a character using the current attribute
51406 $C8CE Handles underline off character, CHR$(130) 52274 $CC32 Displays a character using the previous attribute
51413 $C8D5 Handles flash on character, CHR$(15) 52276 SCC34 Displays a character at the current cursor position
51420 $C8DC Handles flash off character, CHR$(143) 52315 $CC5B Returns height and width of current screen window
51427 $C8E3 Handles insert character, CHR$(148) 52330 $CC6A Reads or sets the current cursor position
51483 $C91B Handles delete character, CHR$(20} 52386 $CCA2 Defines a programmable function key
51506 $C932 Restores the cursor row and column positions 52512 SCD20 Calculates the offset to the start of key definition
51517 SC93D Deletes a character in a logical line string
51535 $C94F Handles tab character, CHR$(9) 52524 $CD2C Changes screen displays (ESC X)
51553 $C961 Handles clear/set tab stop character, CHR$(24) 52526 $CD2E Switches active screen displays
51564 $C96C Tests tab stop bit for current cursor position 52567 $CD57 Sets cursor position on 80-column screen
51584 $C980 Clears all tab stops (ESC Z) 52591 $CD6F Turns cursor on
51587 $C983 Sets default tab stops (ESC Y) 52639 $CD9F Turns cursor off
51598 $C98E Handles bell character, CHR$(7) 52682 $CDCA Writes a byte value to SO-column chip memory
51633 $C9B1 Handles line feed character, CHR$(10) 52684 $CDCC Writes to an 80-column chip register
51646 $C9BE Handles ESC sequences 52696 $CDD8 Reads a byte value from 80-column chip memory
51678 $C9DE Table of ESC key dispatch addresses 52698 $CDDA Reads from an 80-column chip register
51732 $CA14 Defines the upper left corner of the window (ESC T) 52710 $CDE6 Sets the current address in 80-column screen memory
51734 $CA16 Defines the lower right comer of the window (ESC B) 52729 $CDF9 Sets the current address in 80-column attribute
51739 $CA1B Sets window boundaries memory
51748 $CA24 Resets the window to full screen size 52748 $CE0 Initializes character definitions for BO-column screen
51773 $CA3D Inserts a blank line (ESC I) 52812 $CE4C Table of color character translation values
51794 $CA52 Deletes the current logical line (ESC D) 52828 SCE5C Table of 8563 color code translation values
51830 $CA76 Erases to the end of the current logical line (ESC Q) 52844 SCE6C Table of bit mask values
51851 $CA8B Erases to the start of the current logical line (ESC P) 52852 SCE74 Tables of default screen editor variables
51871 $CA9F Erases to the end of the window (ESC (a)} 52904 $CEA8 Table of standard function key definitions
51900 $CABC Scrolls the display up one line (ESC V) 52981-53247 $CEF5-$CFFF Unused
51914 $CACA Scrolls the display down one line (ESC W)
51938 $CAE2 Enables screen scrolling (ESC L)
51941 $CAE5
51946 $CAEA
Disables screen scrolling (ESC M)
Cancels autoinsert mode (ESC C)
Chapter 8: Hardware Chip Registers, Color RAM,
51949 $CAED Enables autoinsert mode (ESC A) and Character ROM
51954 $CAF2 Changes 80-column cursor to solid block (ESC S) VIC (40-Column) Video Chip Registers
51966 $CAFE Changes 80-column cursor to underline (ESC U) 53248 $D000 Sprite 0 horizontal position register
51979 $CB0B Disables cursor blinking (ESC E) 53249 $D001 Sprite 0 vertical position register
52001 SCB21 Enables cursor blinking (ESC F) 53250 SD002 Sprite 1 horizontal position register
53251 $D003 Sprite 1 vertical position register
680
681
53252 $D004 Sprite 2 horizontal position register 54281 $D409 Pulsewidth for voice 2 (low byte)
53253 $D005 Sprite 2 vertical position register 54282 $D40A Pulsewidth for voice 2 (high byte)
53254 $D006 Sprite 3 horizontal position register 54283 JD40B Control register for voice 2
53255 $D007 Sprite 3 vertical position register 54284 $D40C Attack/decay register for voice 2
53256 $D008 Sprite 4 horizontal position register 54285 $D40D Sustain/release register for voice 2
53257 $D009 Sprite 4 vertical position register 54286 $D40E Frequency register for voice 3 (low byte)
53258 $D00A Sprite 5 horizontal position register 54287 $D40F Frequency register for voice 3 (high byte)
53259 $D00B Sprite 5 vertical position register 54288 $D410 Pulsewidth for voice 3 (low byte)
53260 $D00C Sprite 6 horizontal position register 54289 $D411 Fulsewidth for voice 3 (high byte)
53261 $D00D Sprite 6 vertical position register 54290 $D412 Control register for voice 3
53262 $D00E Sprite 7 horizontal position register 54291 $D413 Attack/decay register for voice 3
53263 $D00F Sprite 7 vertical position register 54292 $D414 Sustain/release register for voice 3
53264 $D010 Sprites 0-7 horizontal position (most significant bits) 54293 $D415 Filter cutoff frequency (low byte)
53265 SD011 Control/vertical fine scrolling register 54294 $D416 Filter cutoff frequency (high byte)
53266 $D012 Raster scan line register 54295 $D417 Resonance/filter control register
53267 $D013 Light pen horizontal position 54296 $D418 Volume/filter mode register
53268 $D014 light pen vertical position 54297 $D419 Potentiometer 0 reading
53269 $D015 Sprite enable register 54298 $D41A Potentiometer 1 reading
53270 $D016 Control /horizontal fine scrolling register 54299 $D41B Voice 3 oscillator output
53271 $D017 Sprite vertical expansion register 54300 $D41C Voice 3 envelope generator output
53272 $D018 Memory control register MMU (Memory Management Unit) Chip Registers
53273 $D019 Interrupt flag register 54528 $D500 Configuration register
53274 $D01A Interrupt mask register 54529 $D501 Preconfiguration register A
53275 $D018 Sprite-to-foreground priority register 54530 $D502 Preconfiguration register B
53276 $D01C Sprite multicolor mode register 54531 $D503 Preconfiguration register C
53277 $D01D Sprite horizontal expansion register 54532 $D504 Preconfiguration register D
53278 SD01E Sprite-to-sprite collision register 54533 $D505 Mode configuration register
53279 $D01F Sprite-to-foreground collision register 54534 $D506 RAM configuration register
53280 $D020 Border color register 54535 $D507 Page 0 page pointer
53281 $D021 Background color (source 0) register 54536 $D508 Page 0 block pointer
532S2 $D022 Background color source 1 register 54537 $D509 Page 1 page pointer
53283 $D023 Background color source 2 register 54538 $D50A Page 1 block pointer
53284 $D024 Background color source 3 register 54539 $D50B MMU version register
53285 $D025 Sprite multicolor source 0 register Chip External Registers
VDC (80-column) Video
53286 $D026 Sprite multicolor source 1 register VDC address/status register
54784 $D600
53287 $D027 Sprite 0 color register VDC data register
54785 $D601
53288 $D028 Sprite 1 color register
53289 $D029 Sprite 2 color register VDC Chip Internal Registers
53290 $D02A Sprite 3 color register Total number of horizontal character positions
53291 $D02B Sprite 4 color register Number of visible horizontal character positions
53292 SD02C Sprite 5 color register 2 $02 Horizontal sync position
53293 $D02D Sprite 6 color register 3 $03 Horizontal and vertical sync width
53294 $D02E Sprite 7 color register i $04 Total number of screen rows
53295 SD02F Extended keyboard scan register 5 $05 Vertical fine adjustment
53296 $D030 Processor dock rate control register 6 $06 Number of visible screen rows
7 $07 Vertical sync position
SID (Sound Interface IDevice) Chip Registers Interlace mode control register
8 $08
54272 $D400 Frequency register for voice 1 (low byte) 9 $09 Number of scan lines per character
54273 $D401 Frequency register for voice 1 (high byte) 10 $0A Cursor mode control
54274 $D402 Pulsewidth for voice 1 (low byte) 11 SOB Ending scan line for cursor
54275 $D403 Pulse width for voice 1 (high byte) 12 $0C Screen memory starting address (high byte)
54276 SD404 Control register for voice 1 13 SOD Screen memory starting address (low byte)
54277 $D405 Attack/decay register for voice 1 14 $0E Cursor position address (high byte)
54278 $D406 Sustain/release register for voice 1 15 $0F Cursor position address (low byte)
54279 $D407 Frequency register for voice 2 (low byte) 16 $10 Light pen vertical position
54280 $D408 Frequency register for voice 2 (high byte) 17 $11 Light pen horizontal position
18 $12 Current memory address (high byte)
682 683
.
19 $13 Current memory address {low byte) Controller)
KEC (RAM Expansion Con in Chip Registers
20 $14 Attribute memory starting address (high byte) 57088 SDF00 Status register
21 $15 Attribute memory starting address (low byte) 57089 $DF01 Command register
22 $16 Character horizontal size control register 57090 $DF02 System RAM base address (low byte)
23 $17 Character vertical size control register 57091 $DF03 System RAM base address (high byte)
24 $18 Vertical smooth scrolling and control register 57092 $DF04 Expansion RAM base address (low byte)
25 $19 Horizontal smooth scrolling and control register 57093 $DF05 Expansion RAM base address (high byte)
26 $1A Foreground/background color register 57094 $DF06 Expansion RAM bank
27 $1B Address increment per row 57095 $DF07 Count of bytes to transfer (low byte)
2$ $1C Character set address and memory type register 57096 $DF08 Count of bytes to transfer (high byte)
29 $1D Underline scan line position register 57097 $DF09 Interrupt mask register
30 $1E Number of bytes for block write or copy Address control register
Memory read/write register 57098 $DF0A
31 $1F
32 $20 Block copy source address (high byte) 53248-57343 $D000-$DFFF Character pattern ROM (bank 14)
33 $21 Block copy source address (low byte)
34 $22 Beginning position for horizontal blanking Chapter 9: Kerna
$23 Ending position for horizontal blanking
as
36 S24 Number of memory refresh cycles per scan line 57344 $EO00 Performs power-on/reset sequence
57419 $E04B Table of default MMU register settings
55296 $D800 VIC color memory (two blocks) 57430 $E056 Restores Kemal indirect vectors to their default values
57435 $E05B Loads or copies Kernal indirect vector values
CIA (Complex Interface Adapater)
Ada] Chip #1 Table of default Kernal indirect vector values
57459 E073
56320 $DC00 Port A data I/O register 57491 $E093 Initializes zero page and Kemal pointers
56321 $DC01 Port B data I/O register 57549 $E0CD Initializes all RAM-resident Kernal routines
56322 SDC02 Port A data direction register 57609 $E109 Initializes I/O chip registers
56323 SDC03 Port B data direction register 57820 $E1DC Initializes 80-column video chip registers
56324 $DC04 Timer A latch/counter (low byte) 57840 $E1FO Initializes or jumps through the soft reset vector
56325 $DC05 Timer A latch/counter (high byte) 57892 $E224 Initializes the soft reset vector
56326 $DC06 Timer B latch/counter (low byte) 57922 $E242 Checks for the presence of 64 cartridges or 128 func-
56327 $DC07 Timer B latch/counter (high byte) tion ROMs
56328 $DC08 Time-of-day dock (1/10 seconds) 57931 $E24B Switches the system into 64 mode
56329 $DC09 Time-of-day clock (seconds) 57963 $E26B Logs 128 function ROMs
56330 $DC0A Time-of-day Hock (minutes) 58052 $E2C4 Initialization test pattern
56331 $DC0B Time-of-day clock (hours) 58055 $E2C7 Table of default VIC chip register values
56332 $DC0C Serial data register 58104 $E2FS Table of default 8563 chip register values
56333 SDCOD Interrupt control register 58171 $E33B Sends TALK command to a serial device
56334 $DC0E Control register A 58174 $E33E Sends LISTEN command to a serial device
56335 $DC0F Control register B Sends buffered byte to a serial device
58252 $E38C
CIA (Complex Interface Ada] 58430 $E43E Reads a byte from a serial device
58578 $E4D2 Sends secondary address after LISTEN
56576 $DD00 Port A data I/O register Allows the serial bus ATN output line to go high
56577 $DD01 Port B data I/O register 58583 $E4D7
58592 $E4E0 Sends secondary address after TALK
56578 SDDO2 Port A data direction register Performs talk-listen turnaround
56579 $DD03 Fort B data direction register 58601 $E4E9
58627 $E503 Sends a byte to a serial device
56580 $DD04 Timer A latch/counter (low byte) Sends UNTALK command to a serial device
56581 $DD05 Timer A latch/counter (high byte) 58645 $E515
58662 $E526 Sends UNLISTEN command to a serial device
56582 $DD06 Timer B latch/counter (low byte) Allows serial bus CLK output line to go high
56583 $DD07 Timer B latch/counter (high byte) 58693 $E545
58702 $E54E Fulls serial bus CLK output line low
56584 $DD08 Time-of-day clock (1/10 seconds) Allows serial bus DATA output line to go high
56585 $DD09 Time-of-day clock (seconds) 58711 $E557
58720 $E560 Pulls serial bus DATA output line low
56586 $DD0A Time-of-day clock (minutes) Reads the serial bus DATA and CLK input lines
56587 $DD0B Time-of-day clock (hours) 58729 $E569
58739 $E573 Disables IRQ interrupts and standardizes timing dur-
56588 $DD0C Serial data register ing I/O operations
56589 $DD0D Interrupt control register
Control register A 58783 $E59F Reenables interrupts and restores clock mode after
56590 $DD0E I/O operations
56591 $DD0F Control register B
I/O Expansion Slot #1 58812 $E5BC Performs fast serial turnaround
56832-57087 $DE00-$DEFF
57088-57343 I/O Expansion Slot #2 58819 $E5C3 Sets serial device for fast serial input
$DF00-$DFFF
684 685
58838 SE5D6 Sets serial device for fast serial output 61128 $EEC8 Handles FLAG interrupts for tape
58875 $E5FB Sets serial device for fast serial input or output 61136 $EED0 Controls tape motor interlock
58879 $E5FF Prepares next bit for RS-232 transmission 61163 $EEEB Retrieves a byte from the current input device
58907 $E61B Prepares parity and stop bits 61190 $EF06 Accepts a byte from the current input device
58948 $E644 Prepares to send a stop bit 61224 $EF28 Accepts a byte from tape
58954 $E64A Prepares to transmit next byte 61276 $EF5C Accepts a byte from a serial device
59007 $E67F Sets CIA interrupt register and RS-232 activity flag 61287 $EF67 Accepts a byte from RS-232
59022 $E68E Computes bit count for the RS-232 operation 61305 $EF79 Sends a byte to the current output device
59037 $E69D Processes received bits 61332 $EF94 Sends a byte to tape
59058 $E6B2 Tests for stop bit 61367 $EFB7 Sends a byte to the RS-232 port
59074 $E6C2 Prepares to receive next byte 61373 SEFBD Opens a logical file to a specified device
59092 SE6D4 Tests for start bit 61430 $EFF6 Opens a file for input or output to tape
59103 $E6DF Stores received character in buffer and checks parity 61504 JF040 Opens a file for RS-232 communications
59177 $E729 Handles CKOUT for RS-232 device 61616 $F0B0 Sets up CIA #2 ports for RS-232 communications
5922B $E75C Handles BSOUT for RS-232 device 61643 $F0CB Opens a file for serial bus communications
59285 $E795 Handles CHKIN for RS-232 device 61702 $F106 Sets the current input file for GETIN and BASIN
59342 $E7CE Handles GETIN for RS-232 device 61735 $F127 Prepares a serial device file for input
59372 $E7EC Disables RS-232 activity during tape or serial bus 61772 $F14C Sets the current output file for BSOUT
operations 61805 SF16D Prepares a serial device file for output
59397 $E805 Handles NMI interrupts for RS-232 61832 $F188 Closes a specified logical file
59472 $E850 Table of baud rate timing constants for NTSC 61S65 $F1A9 Closes a tape file
systems 61903 $F1CF Closes a file on a serial device
59492 $E864 Table of baud rate timing constants for PAL systems 61924 $F1E4 Removes an entry from the logical file tables
59512 $E878 Reads a bit from RS-232 device 61954 $F202 Checks whether a file is already open
59561 $E8A9 Initiates reception of RS-232 byte 61970 $F212 Loads parameters for a logical Sle
59600 $E8D0 Reads next header block from tape 61986 $F222 Clears file table entries
59673 $E919 Writes a header block to tape 61990 $F226 Resets default I/O channels
59776 $E980 Loads and tests cassette buffer address 62013 $F23D Closes all open files for a specified serial device
59783 $E987 Sets buffer address as block address 62053 $F265 Loads or verifies a program file from disk or tape
59802 $E99A Searches for a specified header 62075 F276 Loads or verifies a file from a serial device
59838 SE9BE Checks for cassette buffer filled or emptied 62246 $F326 Loads or verifies a program file from tape
59848 $E9C8 Requests PLAY button if necessary 62369 $F3A1 Attempts to set up fast serial load or verify
59871 $E9DF Checks tape buttons 62442 $F3EA Loads or verifies a file using fast serial burst mode
59881 $E9E9 Requests RECORD and PLAY buttons if necessary 62616 $F496 Handles read error during burst mode load/verify
59890 $E9F2 Reads next header or data block from tape 62630 $F4A6 Stops burst mode load/verify if RUN/STOP key
59899 $E9FB Reads or verifies a block from tape pressed
59925 $EA15 Writes a header or data block to tape 62642 SF4B2 Aborts burst mode load/verify if maximum address
59928 $EA18 Writes a block to tape exceeded
59942 $EA26 Initiates tape I/O operation 62650 SF4BA Reads a byte using fast serial hardware
60047 $EA8F Checks for RUN/STOP keypress during tape 6266] SF4C5 Loads or verifies a block of data using burst mode
operations 62723 $F503 Toggles state of serial bus CLK line
60065 $EAA1 Sets timer A to check FLAG interrupts 62735 SF50F Displays SEARCHING FOR message
60139 $EAEB Reads or verifies a block of data from tape 62771 $F533 Displays LOADING or VERIFYING message
60753 $ED51 Loads working pointer with starting address 62782 SF53E Saves a block of memory to tape or disk
60762 $ED5A Initializes tape variables between each byte 62817 $F561 Saves a block of memory to a serial device
60777 $ED69 Initiates writing of a tape half-dipoie 62878 SF59E Closes a file on a serial device
60816 $ED90 Writes a block of data to tape 62901 $F5B5 Aborts LOAD or SAVE to serial device
60974 $EE2E Writes a leader to tape and prepares to write a data Displays SAVING message and filename
62908 $F5BC
block 62920 $F5C8 Saves a block of memory to tape
61015 $EE57 Restores IRQ vector and operating modes after tape 62968 $F5F8 Updates jiffy timers and checks RUN/STOP key
operation column
61077 $EE95 Ends tape write interrupts 63037 $F63D Scans RUN/STOP key column
61083 $EE9B Loads IIRQ vector for tape operation 63070 $F65E Reads the software jiffy clock
61104 $EEB0 Turns cassette motor off 63077 $F665 Sets the software jiffy clock
6U11 $EEB7 Tests whether ending address has been reached 63086 $F66E Tests for a RUN/STOP keypress
61121 $EECI Increments the working pointer 63100 Handles Kemal I/O errors
$F67C
686 687
63152 $F6B0 Table of Kernal control messages
63262 $F71E 65369 $FF59 Entry point for the Kernal LKUPLA routine
Handles Kemal control messages Entry point for the Kernal LKUTSA routine
63281 $F731 65372 $FF5C
Sets the length and address of filename for I/O $FF5F Calls the screen editor SWAPPER routine
65375
63288 SF738 operations 65378 $FF62 Calls the screen editor INIT80 routine
Sets logical file number, device number, and second- 65381 $FF65 Calls the screen editor KEYSET routine
ary address for I/O operations $FF68 Entry point for the Kemal JSETBNK routine
63295 $F73F Sets data and filename banks for I/O operations 65384
63300 $F744 65387 $FF6B Entry point for the Kemal GETCFG routine
Reads the tape/serial or RS-232 status byte $FF6E Entry point for the Kernal JSRFAR routine
63324 $F75C Sets the Kemal message control flag 65390
63327 $F75F 65393 $FF71 Entry point for trie Kemal JMPFAR routine
Sets the IEEE timeout flag $FF74 Entry point for the Kemal INDFET calling routine
63331 $F763 Sets or reads the system's top-of-memory pointer 65396
63346 $F772 65399 $FF77 Entry point for the Kemal INDSTA calling routine
Sets or reads the system's bottom-of-memory pointer Entry point for the Kemal INTJCMP calling routine
63361 $F781 Returns base address of I/O block 65402 $FF7A
63366 $F?86 65405 $FF7D Entry point for the Kemal PRIMM routine
Checks whether a secondary address value is used Calls the screen editor CINT routine
63389 $F79D Checks whether a logical file number value is used 65409 $FF81
63397 65412 $FF84 Entry point for the Kernal IOINIT routine
$F7A5 Performs a DMA operation Entry point for the Kemal RAMTAS routine
63406 $F7AE Retrieves a character from the current filename 65415 $FF87
63420 65418 $FF8A Entry point for the Kemal RESTOR routine
$F7BC Writes a byte value to memory Entry point for the Kemal VECTOR routine
63423 $F7BF Writes a byte value to memory 65421 SFF8D
63433 65424 $FF90 Entry point for the Kemal SETMSG routine
$F7C9 Reads a byte value from memory Entry point for the Kemal SECOND routine
63436 $F7CC Reads a byte value from memory 65427 $FF93
65430 $FF96 Entry point for the Kemal TKSA routine
63440 $F7D0 Retrieves a character from any bank Entry point for the Kemal MEMTOP routine
63450 $F7DA Stores the accumulator contents in any bank 65433 $FF99
65436 $FF9C Entry point for the Kernal MEMBOT routine
63459 $F7E3 Compares the accumulator contents with a value Calls the screen editor SCNKEY routine
from any bank 65439 $FF9F
65442 $FFA2 Entry point for the Kemal SETTMO routine
63468 $F7EC Translates a bank number into an MMU register Entry point for the Kemal ACPTR at routine
setting 65445 $FFA5
65448 $FFA8 Entry point for the Kemal C1OUT routine
63472 $F7F0 Table of MMU register settings for standard banks Entry point for the Kemal UNTLK routine
63488 $F800 65451 $FFAB
Code for Kemal RAM-based subroutines $FFAE Entry point for the Kemal UNLSN routine
63591 $F867 65454
Initializes function ROMs and attempts to boot a disk 65457 $FFB1 Entry point for the Kemal L1STN routine
in the default drive 65460 $FFB4 Entry point for the Kernal TALK routine
63632 SF890 Attempts to boot a disk Entry point for the Kemal READSS routine
63883 $F98B 65463 $FFB7
Resets the disk drive $FFBA Entry point for the Kemal SETLFS routine
63923 $F9B3 65466 Entry point for the Kemal SETNAM routine
Loads additional b< Jt sectors 65469 $FFBD
63995 $F9FB Converts a byte value into two ASCII digits Entry point for the Kemal OPEN routine
64008 $FA08 65472 $FFC0 Entry point for the Kemal CLOSE routine
Table of disk commands for booting 65475 $EFC3
64023 $FA17 Handles PRIMM (print immediate) function Entry point for the Kemal CHKIN routine
64064 $FA40 65478 $FFC6 Entry point for the Kernal CKOUT routine
Handles NMI interrupts 65481 $FFC9
64101 $FA65 Handles IRQ interrupts Entry point for the Kemal CLRCH routine
64128 $FA80 65484 $FFCC Entry point for the Kemal BASIN routine
Standard keyboard decoding tables 65487 $FFCE
M M U (Memory Management Unit) Chip Registers Entry point for the Kernal BSOUT routine
65490 $FFD2 Entry point for the Kemal LOAD routine
65280 5FF00 Configuration register 65493 $FFD5
65281 $FF01 Load configuration register A Entry point for the Kemal SAVE routne
65496 $EFD8 Entry point for the Kemal SETT1M routine
65282 $FF02 Load configuration register B 65499 $FFDB
65283 $FF03 Load configuration register C Entry point for the Kernal RDTIM routine
65502 $FFDE Entry point for the Kernal STOP routine
65284 $FF04 Load configuration register D 65505 $FFE1
65285 $FF05 Jump to NMI handler routine Entry point for the Kemal GETIN routine
65508 $FFE4 Entry point for the Kemal CLALL routine
65303 $FF17 65511 $FFE7 Entry point for the Kemal UDTIM routine
Jump to IRQ or BRK handler routine 65514 $FFEA
65331 $FF33 Common exit routine for all interrupt routines Calls the screen editor SCRORG routine
65341 SFF3D 65? 17 $FFED Calls the screen editor PLOT routine
Jump to reset handler routine 65520 $FFF0
65351 $FF47 Entry point for the Kemal SPIIsLSPOUT routine Entry point for the Kernal IOBASE routine
65354 $FF4A 65523 $FFF3 Soft reset vector (bank 1)
Entry point for the Kemal CLOSF_J\LL routine 65528 $FFF8
65357 $FF4D Entry point for the Kemal C64—MODE routine Processor NMI vector
65360 $FF50 65530 $FFFA Processor reset vector
Entry point for the Kema! DMA_CALL routine 65532 SFFFC
65363 $FF53 Entry point for the Kemal BOOT_CALL routine Processor BRK/IRQ vector
65366 65534 $IH1:
SFF56 Entry point for the Kemal PHOENIX routine
688 689
H ere's the complete guire to understanding the inner
workings of the Comrodore 128. Collected in this one
volume are the answe's to practically any questions you
might have about thy -vav +he Commodore 128 operates.
Moreover, the information presented here isn't just edu-
cational—it has tremendous practical value as well. Increas-
ing your understanding of how the computer operates puts
you more fully in control. Whether you program in BASIC or
machine language, or whether you are just starting out or
are an expert programmer, you'll find that this book unlocks
secrets of the 128 that will allow you to write more powerful
and more sophisticated programs. Inside you'll find:
• A complete reference to BASIC, the Kerndl, the screen edi-
tor, even the machine language monitor. Not just a list of
addresses, but detailed discussions of all the important ROM
routines.
« Thorough descriptions of all the video, sound, and Interface
chips—VIC, SID, VDC, MMU, CIA, and REC. Every register of
every chip is explained in detail.
• A clear and straightforward explanation of how the 128's
elaborate memory management system operates, and how
you can create your own custom memory configurations.
• Hundreds of suggestions and hints on how to take full ad-
vantage of the 128's enhanced capabilities.
- Examples of ways you can modify and improve the per-
formance of your computer, including how to add new
statements to BASIC and how to customize Kernal functions.
• Explanations of the bugs in BASIC and the Kernal, and how
to avoid them.
If you've mastered the fundamentals of your 128 and are
seeking to expand your knowledge of this powerful, versatile
system. Mapping the Commodore 128 can be your guide, If
you're a veteran programmer who moved up to the 128
after years of experience on an older Commodore model,
this book will help you adapt your established techniques to
your new machine. For advanced programmers. Mapping
the Commodore 128 provides a wealth of ideas for exciting
new programming projects, Much of the information gath-
ered here is available elsewhere only in bits and scraps, if at
all. You'll want to keep a copy close at hand every time you
turn on your 128,
ISBN 9-87455-060-2