%
% 256 kB internal RAM expansion for the Commodore 64
%
% This document can be compiled to a DeVice Independent file
% using the following software:
%
%       TeX 3.1415
%       LaTeX 2.09 or LaTeX 2e
%
%% \documentstyle{article} % for LaTeX 2.09
\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{pslatex}
\usepackage[dvipdfm]{hyperref}
%
% Define an \overbar command for drawing a bar over some words
%
\newbox\obox
\def\overbar#1{\setbox\obox \hbox{#1}%
\hbox{\raise1.8ex\hbox to 0pt{\vrule height 0.4pt width \wd\obox\hss}%
\copy\obox}}
%% %
%% % Enable duplex printing for PostScript printers
%% %
%% \special{!%
%%   statusdict /duplexmode known
%%   { /CDM statusdict begin duplexmode end def
%%     statusdict begin false setduplexmode end }
%%   if
%% }
%
% Select page size DIN A4
%
\topmargin=-36bp
\oddsidemargin=0bp
\evensidemargin=-18bp
\textheight=9in
\textwidth=6.5in
%
% Begin
%
\begin{document}
\title{Memory expansions for the Commodore~64}
\author
{
  Marko M\"akel\"a
    \and
  Pekka Pessi
}
\date
{
  January--February, 1987 \\
  April 17, 1994 \\{}
  [last essential modification on December 22, 1999]%
  \footnote
  {
    This document is based on Pekka Pessi's two articles
    describing an 256~kB internal memory expansion for the
    Commodore~64. The articles were originally published in the
    largest Nordic and Finnish home computer users' magazine,
    MikroBITTI, in its first two issues in the year 1987. Six years
    later, they were translated to English and edited by Marko M\"akel\"a,
    with help from Pekka Pessi. This is a fourth, corrected and improved
    version of the document.
  }
  \footnote
  {
    August 1996: Thanks to Wolfgang Scherr from Austria, who noticed my
    mistake in the schematic diagram.  The inputs of the 74LS153 chip were
    mixed, which caused the address block decoding to fail.
  }
  \footnote
  {
    December 1999: By now, I know of two 64s and four 128s where this
    expansion has been built.  The expansion never became a success,
    although the banked concept is technically better than the
    Commodore REU.
  }
  \footnote
  {
    January 2006: Thanks to Marco van den Heuvel, who implemented the
    expansion in the emulator VICE 1.19, for pointing out errors in
    the first sample code for initializing the PIA.
  }
}

\maketitle

\begin{sl}
Commodore~64 becomes remarkably more efficient by adding memory to it. Then the
worst slow-down, incredibly slow disk drive, can be worked around by using a
part of the memory as a RAM disk.

In 1986, when the original article was written, there were no
commercial memory extensions for sale in Finland.%
\footnote
{
  Commodore's RAM Expansion Units came to our market in the year 1987.
}
Of course there were some in the USA, but they were quite useless, as
they had only 64~kB of memory, and the price was high as well. When built by
oneself, the following memory expansion should have costed 300--400 Finnish
marks.%
\footnote
{
  One American dollar (USD) is equivalent to five or six Finnish
  marks (FIM). I constructed my expansion in 1993 March, and it costed
  111~FIM. It could easily have been about 20~FIM cheaper.
}
\end{sl}

\medskip

Many goals were set to the expansion. As many programs as possible
should work also with it installed. This means that there could not be
any radical changes to the memory map.

The address space of an expanded machine really remains same for a
usual programmer. After reset, the computer doesn't differ from an
unexpanded one practically at all.

Even taking a look at the machine from outside doesn't reveal the
expansion, as Pekka needed the expansion port for his IEEE-488
interface cartridge, also designed by himself.

The memory expansion is built in the machine on an add-on card. As the
mother board remains the same --- no traces are cut --- the expansion
can be removed without a soldering iron.

The design aimed to a hardware that supports programming. While making
the RAM disk program, Pekka changed the hardware several times, until
he was satisfied with it.

\newpage
\tableofcontents
\newpage

\section{Some basics}

\subsection{Expansion memory in 16~kB blocks}

The processor of Commodore~64, MOS~6510, has an 8-bit data bus, and
its address bus is 16 bits wide. Like other 8-bit processors, it can
address only 64~kB of memory at a time. In most 8-bit computers, the
memory is limited to these 64 kilobytes. How could one add memory
above this limit?

The solution is simple: the memory is divided into banks of no more
than 64~kB, which are switched on and off. Some processors have been
added a special circuit for this purpose, in which case the executing
program can be in its own 64~kB bank and the processed data in another
bank. For example, MOS~6509, a fellow processor of MOS~6510, works in
this way, enabling access to one megabyte. The Commodore~128 uses a
sophisticated chip, MOS~8722~MMU (Memory Management Unit), which lets
you to activate one 64~kB memory bank of a total of two memory banks
at a time.

Our expansion divides the 256~kB of memory to sixteen blocks of
sixteen kilobytes each. The processor can address up to four of them
at a time. Every four 16~kB segment of the address space can be mapped
to any 16~kB block. Figure~\ref{MemoryMap} shows the mapping right
after startup.

However, the video chip VIC-II --- MOS~6569\footnote{6567 for NTSC}
--- retrieves its data from the memory outside the normal bus. The
internal address registers of VIC-II are 14 bits wide, so it can
address only 16~kB without external logic. The required two extra bits
for accessing the whole 64~kB video bank are provided from the second
CIA chip. Our extra logic provides additional two address bits for
accessing the whole 256~kB of video memory.

\begin{figure}
\setlength{\unitlength}{.75ex}
\begin{center}
\begin{picture}(80,101)(-40,-1)
% Captions
\put(-10,98){\makebox(20,2){\bf RAM pool}}
\put(-40,98){\makebox(20,2){\bf MPU's RAM}}
\put(20,98){\makebox(20,2){\bf VIC-II's RAM}}
% The frames
\thicklines
% Vertical lines
\put(-10,0){\line(0,1){96}}\put(10,0){\line(0,1){96}}
\put(-40,48){\line(0,1){48}}\put(-20,48){\line(0,1){48}}
\put(20,48){\line(0,1){48}}\put(40,48){\line(0,1){48}}
% Horizontal lines
\multiput(-10,0)(0,6){17}{\line(1,0){5}}
\multiput(10,0)(0,6){17}{\line(-1,0){5}}
\multiput(-40,48)(0,12){5}{\line(1,0){5}}
\multiput(-20,48)(0,12){5}{\line(-1,0){5}}
\multiput(20,48)(0,12){5}{\line(1,0){5}}
\multiput(40,48)(0,12){5}{\line(-1,0){5}}
\thinlines
% Vectors
\put(-20,90){\line(1,0){3}\line(0,1){3}}\put(-17,93){\vector(1,0){7}}
\put(-20,78){\line(1,0){4}\line(0,1){9}}\put(-16,87){\vector(1,0){6}}
\put(-20,66){\line(1,0){5}\line(0,1){15}}\put(-15,81){\vector(1,0){5}}
\put(-20,54){\line(1,0){6}\line(0,1){21}}\put(-14,75){\vector(1,0){4}}
\put(17,93){\vector(-1,0){7}}\put(20,90){\line(-1,0){3}\line(0,1){3}}
\put(16,87){\vector(-1,0){6}}\put(20,78){\line(-1,0){4}\line(0,1){9}}
\put(15,81){\vector(-1,0){5}}\put(20,66){\line(-1,0){5}\line(0,1){15}}
\put(14,75){\vector(-1,0){4}}\put(20,54){\line(-1,0){6}\line(0,1){21}}
% Addresses
\put(-5,-1){\makebox(10,2){\tt\$00000}}
\put(-5,5){\makebox(10,2){\tt\$04000}}
\put(-5,11){\makebox(10,2){\tt\$08000}}
\put(-5,17){\makebox(10,2){\tt\$0C000}}
\put(-5,23){\makebox(10,2){\tt\$10000}}
\put(-5,29){\makebox(10,2){\tt\$14000}}
\put(-5,35){\makebox(10,2){\tt\$18000}}
\put(-5,41){\makebox(10,2){\tt\$1C000}}
\put(-5,47){\makebox(10,2){\tt\$20000}}
\put(-5,53){\makebox(10,2){\tt\$24000}}
\put(-5,59){\makebox(10,2){\tt\$28000}}
\put(-5,65){\makebox(10,2){\tt\$2C000}}
\put(-5,71){\makebox(10,2){\tt\$30000}}
\put(-5,77){\makebox(10,2){\tt\$34000}}
\put(-5,83){\makebox(10,2){\tt\$38000}}
\put(-5,89){\makebox(10,2){\tt\$3C000}}
\put(-5,95){\makebox(10,2){\tt\$40000}}
\put(-35,47){\makebox(10,2){\tt\$0000}}
\put(-35,59){\makebox(10,2){\tt\$4000}}
\put(-35,71){\makebox(10,2){\tt\$8000}}
\put(-35,83){\makebox(10,2){\tt\$C000}}
\put(-35,95){\makebox(10,2){\tt\$10000}}
\put(25,47){\makebox(10,2){\tt\$0000}}
\put(25,59){\makebox(10,2){\tt\$4000}}
\put(25,71){\makebox(10,2){\tt\$8000}}
\put(25,83){\makebox(10,2){\tt\$C000}}
\put(25,95){\makebox(10,2){\tt\$10000}}
% Labels
\put(-10,2){\makebox(20,2){Block \tt 0}}
\put(-10,8){\makebox(20,2){Block \tt 1}}
\put(-10,14){\makebox(20,2){Block \tt 2}}
\put(-10,20){\makebox(20,2){Block \tt 3}}
\put(-10,26){\makebox(20,2){Block \tt 4}}
\put(-10,32){\makebox(20,2){Block \tt 5}}
\put(-10,38){\makebox(20,2){Block \tt 6}}
\put(-10,44){\makebox(20,2){Block \tt 7}}
\put(-10,50){\makebox(20,2){Block \tt 8}}
\put(-10,56){\makebox(20,2){Block \tt 9}}
\put(-10,62){\makebox(20,2){Block \tt A}}
\put(-10,68){\makebox(20,2){Block \tt B}}
\put(-10,74){\makebox(20,2){Block \tt C}}
\put(-10,80){\makebox(20,2){Block \tt D}}
\put(-10,86){\makebox(20,2){Block \tt E}}
\put(-10,92){\makebox(20,2){Block \tt F}}
\multiput(-40,53)(60,0){2}{\makebox(20,2){Segment \tt 0}}
\multiput(-40,65)(60,0){2}{\makebox(20,2){Segment \tt 1}}
\multiput(-40,77)(60,0){2}{\makebox(20,2){Segment \tt 2}}
\multiput(-40,89)(60,0){2}{\makebox(20,2){Segment \tt 3}}
\end{picture}
\end{center}
\caption{Memory mapping right after power-up}
\label{MemoryMap}
\end{figure}

\begin{figure}[hbt]
\setlength{\unitlength}{1.5ex}
\begin{center}
\begin{picture}(50,16)(-5,0)
% Captions
\put(-5,16){\makebox(20,2){\bf 4164}}
\put(25,16){\makebox(20,2){\bf 41256}}
% The Dual-In-Line housings
\thicklines
\multiput(1,0)(30,0){2}{\line(1,0){8}}\multiput(1,0)(30,0){2}{\line(0,1){16}}
\multiput(9,0)(30,0){2}{\line(0,1){16}}\multiput(1,16)(30,0){2}{\line(1,0){8}}
\multiput(5,16)(30,0){2}{\oval(2,2)[b]}\multiput(1.5,15.5)(30,0){2}{\circle{0}}
% The pins
\thinlines
\multiput(0,1)(0,2){8}{\line(1,0){1}}
\multiput(9,1)(0,2){8}{\line(1,0){1}}
\multiput(30,1)(0,2){8}{\line(1,0){1}}
\multiput(39,1)(0,2){8}{\line(1,0){1}}
% The pin numbers
\multiput(2,14)(30,0){2}{\makebox(2,2)[l]{1}}
\multiput(6,14)(30,0){2}{\makebox(2,2)[r]{16}}
\multiput(2,12)(30,0){2}{\makebox(2,2)[l]{2}}
\multiput(6,12)(30,0){2}{\makebox(2,2)[r]{15}}
\multiput(2,10)(30,0){2}{\makebox(2,2)[l]{3}}
\multiput(6,10)(30,0){2}{\makebox(2,2)[r]{14}}
\multiput(2,8)(30,0){2}{\makebox(2,2)[l]{4}}
\multiput(6,8)(30,0){2}{\makebox(2,2)[r]{13}}
\multiput(2,6)(30,0){2}{\makebox(2,2)[l]{5}}
\multiput(6,6)(30,0){2}{\makebox(2,2)[r]{12}}
\multiput(2,4)(30,0){2}{\makebox(2,2)[l]{6}}
\multiput(6,4)(30,0){2}{\makebox(2,2)[r]{11}}
\multiput(2,2)(30,0){2}{\makebox(2,2)[l]{7}}
\multiput(6,2)(30,0){2}{\makebox(2,2)[r]{10}}
\multiput(2,0)(30,0){2}{\makebox(2,2)[l]{8}}
\multiput(6,0)(30,0){2}{\makebox(2,2)[r]{9}}
% The descriptions
\put(-5,14){\makebox(5,2)[r]{NC}}
\put(25,14){\makebox(5,2)[r]{MA8}}
\multiput(10,14)(30,0){2}{\makebox(5,2)[l]{$\rm V_{SS}$}}
\multiput(-5,12)(30,0){2}{\makebox(5,2)[r]{D}}
\multiput(10,12)(30,0){2}{\makebox(5,2)[l]{\overbar{CAS}}}
\multiput(-5,10)(30,0){2}{\makebox(5,2)[r]{\overbar{W}}}
\multiput(10,10)(30,0){2}{\makebox(5,2)[l]{Q}}
\multiput(-5,8)(30,0){2}{\makebox(5,2)[r]{\overbar{RAS}}}
\multiput(10,8)(30,0){2}{\makebox(5,2)[l]{MA6}}
\multiput(-5,6)(30,0){2}{\makebox(5,2)[r]{MA0}}
\multiput(10,6)(30,0){2}{\makebox(5,2)[l]{MA3}}
\multiput(-5,4)(30,0){2}{\makebox(5,2)[r]{MA2}}
\multiput(10,4)(30,0){2}{\makebox(5,2)[l]{MA4}}
\multiput(-5,2)(30,0){2}{\makebox(5,2)[r]{MA1}}
\multiput(10,2)(30,0){2}{\makebox(5,2)[l]{MA5}}
\multiput(-5,0)(30,0){2}{\makebox(5,2)[r]{$\rm V_{DD}$}}
\multiput(10,0)(30,0){2}{\makebox(5,2)[l]{MA7}}
\end{picture}
\caption{The Dynamic Random Access Memory Chips 4164 and 41256}
\end{center}
\end{figure}

\subsection{Memory chips}

Commodore~64 uses 64~kb dynamic RAM chips of JEDEC standard. In 1982,
when the computer was introduced, they were most modern technology,
they needed only one operating voltage supply instead of traditional
three.

The semiconductor memories have developed fast, however, and now a
chip in a DIP of equal size can hold 256 kilobits. The pinout of these
256~kb chips differs minimally from the 64~kb ones. The smaller 64~kb
chips, at least the ones used in C64 and C128, have one unused
contact. The address line to handle three times bigger memory is tied
to this pin. In the DRAMs the address lines are multiplexed: two
address bits use the same pin successively.

In the MikroBITTI article Pekka wrote that 256~kb chips are rather
cheap, and the price would lower as the production rate increases.
Nowadays the production must have almost stopped. When Pekka bought
his chips between March and April of 1986, they costed about 50~FIM
each. When the original article was published, they costed less than
20~FIM. After that the prices rose due to a memory shortage. But
nowadays the chips don't cost practically anything, if you're
lucky. Many users of IBM~PC compatibles want to upgrade their system
memory with 1~Mb chips or alike and would like to get rid of their old
256~kb chips. I bought eight second-hand chips with total 35~FIM, and
later 36 chips with 117~FIM, including shipping. The lowest price of
unused chip I encountered was 13~FIM a piece and the highest was
30~FIM, almost 10 times the price I paid!

The 256~kb chips don't consume significantly more power, so there is
no need for a bigger power supply. However, devices that take their
power directly from the computer can cause problems. You can find this
out by experimenting.

The speed of the chips doesn't prevent the replacement either.
According to its schematics diagram, Commodore 64 can use chips with
access time of 200~nanoseconds.\footnote{Besides, the oldest
Commodore~64 I have uses 300~ns chips housed in ceramic packages.}
Even the slowest 256~kb dynamic RAMs are not that slow.

It might be wise to replace the bypass capacitors near the memory
chips with bigger ones. On the other hand, my machine works well with
the default 10~nF capacitors. If your computer starts to work
unreliably, too small bypass capacitors could be the culprit.

\subsection{Dynamic headaches}
\label{Addressing}

The dynamic RAM chips are organized in rows and columns. In 64~kb
chips, a row is 256 bits wide, and in 256~kb ones it is 512 bits
wide. Also the memory address is divided into row and column
addresses. When a bit is being accessed in the dynamic RAM, the row
address is asserted before the column address.

First the interfacing circuitry puts the row address on the
Multiplexed Address bus, while the video chip asserts the
\overbar{RAS} (Row Address Select) signal for a short period. After
that, the video chip pulls the \overbar{CAS} (Column Address Select)
line low, and the interfacing circuitry places the column address on
the bus. After all this, the bits in that position can be read or
written.

The computer has two circuitries that take care of this multiplexing.
The multiplexers U13 and U25 form the address when the processor has
the bus, whereas the video chip produces the row and column addresses
itself when it needs its screen data.

You could access a set of nearby locations faster, if you specified
the row address only once, and then produced only the column addresses
for each location. This technique is supported in the Acorn Archimedes
computer on the processor level, and some other computers utilize it
with external circuitry as memory interleaving. The Commodore,
however, does not have to hassle with this, as its system clock rate
is so slow. As a matter of fact, it actually uses the least
significant processor address bits (A0--A7) as a row address and the
most significant bits (A8--A15) as the column address.

\subsection{Memory refresh}

A dynamic memory chip stores the data bits as charged tiny capacitors,
which discharge among the time. The data must be refreshed
periodically, every 2--4 milliseconds, by recharging the capacitors.

If the whole contents of the memory was refreshed simultaneously, the
power peak would cause enormous problems. Only a block of one or two
rows can be refreshed at a time. The 64~kb chips have 128 blocks to be
refreshed, which implies a 7-bit refresh counter ($2^7$ equals 128).

In order to avoid disturbance, 256~kb chips must have more blocks.
Thus they require a longer refresh counter (8 bits). As the amount of
refresh cycles has increased, the capacitors' ability of keeping
charge has been improved. The 64 kilobit DRAMs required 128 refresh
cycles every 2 milliseconds, now the 256~kb chips need 256 cycles but
every 4~ms.

Whenever you select a row address,\footnote{See Section
\ref{Addressing}.} the block to which the row address belongs gets
refreshed. As the 64 kilobit chips have a 7-bit refresh counter, the
lowest seven row address bits specify the row address, and the highest
bit is ignored. The 256 kilobit memory chips have an 8-bit counter,
so they ignore the 9th row address bit and determine the block to be
refreshed by the eight lowest bits.

The VIC-II chip refreshes the memory systematically, 5 rows in the
end of each screen scan line. It does this by selecting a row address
determined by its internal counter, and then increases this counter by
one. The video chip could have only 7-bit refresh counter, and it
would still operate with 64~kb chips, but fortunately it has an 8-bit
counter, so all of the 256~kb chips get refreshed.

Newer memory chips can be refreshed using a CAS-before-RAS technique.
In this technique, you pull first the \overbar{CAS} signal low, and
then the \overbar{RAS} signal. The memory chips recognize this as a
memory refresh condition, and they refresh a block and increase their
internal refresh counter. However, this technique was not available
when the Commodore~64 and its video chip were designed.

\section{Building the expansion}
\subsection{Disclaimer}

Although this procedure worked perfectly for me, I cannot guarantee
that anyone else can perform this upgrade without damaging their
computer.  I therefore disclaim any responsibilty for any damage that
may occur as a result of attempting this upgrade. It will also void
any warranty on your computer.

On a more positive note, there is no reason why someone who is
experienced in wielding a soldering iron, and has done some electronic
construction or troubleshooting, should not be able to perform this
upgrade successfully.

\subsection{Getting started}

A termostate soldering iron, desoldering pump or other desoldering
tool, a screwdriver, a spoon and a continuity tester are the only
tools needed. The spoon is for removing the chips. A bottle top
remover is not suitable for that.%
\footnote
{
  A tiny screwdriver is equally good. Just insert the screwdriver tip
  under one end of the chip and wound it a bit in upward angle so that
  the chip moves slightly. Then insert it to the other end of the chip
  and try to lift it a bit. You may have to repeat this procedure. Be
  careful not to wound the pins too much.
}
The continuity tester is vital for checking suspicious connections. If
your tester does not automatically select proper measuring range, use
the coarsest (M$\Omega$) range, as it uses smallest current, which
shouldn't damage any chips on the board.

The installation begins of course by opening the machine and removing
the keyboard and LED cables. It is useful to memorize, photograph or
draw how the parts were initially connected.

After removing the cables, remove the aluminum cardboard shield and
open the screws that hold the motherboard with the case, and remove
the board.

The expansion consists of one daughter board, which contains most
of the added logic, one piggy-backed chip, and a spaghetti of wires.

In Figure \ref{PIAschematics}, there is a schematics diagram of the
daughter board for the expansion. There are some signals that you must
wire to the mother board. You can take the \overbar{I/O2} and A7
signals from the cartridge port, or from some through-put location
near the daughter board. The \overbar{I/O2} signal should be on the
pin~9 of the chip U15 (74LS139). The A7 can also be taken from the
6510's pin 14, or from the multiplexor U13 (74LS257), pin~10.

The MA8 signal is the new Multiplexed Address line for the memory
chips and should be soldered to the pin~1 of each chip. All the
remaining five signals on the right edge of the diagram interface to
the multiplexor chip U13. The \overbar{CAS} signal goes to pin~1. To
interface the address lines A14, A15, B14 and B15, you have to
desolder two pins of the multiplexor, 11 and 2. The signal A15 should
then be wired to the mother board contact under the multiplexor
pin~11, or to the 6510's pin~23, and the signal B15, the relocated
address line should be soldered to the multiplexor's pin~11.
Similarly, the contacts A14 and B14 should be connected to the system
bus line A14 and the U13's pin~2, respectively. Figure \ref{U13_pins}
shows the pinout of the multiplexor chip U13.

\begin{figure}
\setlength{\unitlength}{1.25ex}
\begin{center}
\begin{picture}(64,62)(0,4)
%
% Captions
%
\put(6.8,46){\makebox(6.4,2){\parbox{8ex}{\center\bf U2 M6526}}}
\put(28,25){\makebox(8,2){\parbox{10ex}{\center\bf IC1 MC6821}}}
\put(51,35){\makebox(4,2){\parbox{5ex}{\center\bf IC2 '153}}}
\put(51,15){\makebox(4,2){\parbox{5ex}{\center\bf IC3 '151}}}
%
% The MOS 6526 CIA
%
%% The frame and the pins
\thicklines
\put(2,12){\line(0,1){42}\line(1,0){16}\line(0,1){42}}\put(2,54){\line(1,0){16}}
\thinlines
\multiput(1,16)(0,2){18}{\line(1,0){1}}
\multiput(18,14)(0,2){20}{\line(1,0){1}}
\put(10,54){\vector(0,1){2}}
\put(9,10){\line(1,0){1}\line(0,1){2}\line(1,0){1}}
%% The pin numbers and the labels
\put(0,50){\makebox(1.75,2)[r]{2}}\put(2.25,49){\makebox(4,2)[l]{PA0}}
\put(0,48){\makebox(1.75,2)[r]{3}}\put(2.25,47){\makebox(4,2)[l]{PA1}}
\put(0,46){\makebox(1.75,2)[r]{4}}\put(2.25,45){\makebox(4,2)[l]{PA2}}
\put(0,44){\makebox(1.75,2)[r]{5}}\put(2.25,43){\makebox(4,2)[l]{PA3}}
\put(0,42){\makebox(1.75,2)[r]{6}}\put(2.25,41){\makebox(4,2)[l]{PA4}}
\put(0,40){\makebox(1.75,2)[r]{7}}\put(2.25,39){\makebox(4,2)[l]{PA5}}
\put(0,38){\makebox(1.75,2)[r]{8}}\put(2.25,37){\makebox(4,2)[l]{PA6}}
\put(0,36){\makebox(1.75,2)[r]{9}}\put(2.25,35){\makebox(4,2)[l]{PA7}}
\put(0,34){\makebox(1.75,2)[r]{10}}\put(2.25,33){\makebox(4,2)[l]{PB0}}
\put(0,32){\makebox(1.75,2)[r]{11}}\put(2.25,31){\makebox(4,2)[l]{PB1}}
\put(0,30){\makebox(1.75,2)[r]{12}}\put(2.25,29){\makebox(4,2)[l]{PB2}}
\put(0,28){\makebox(1.75,2)[r]{13}}\put(2.25,27){\makebox(4,2)[l]{PB3}}
\put(0,26){\makebox(1.75,2)[r]{14}}\put(2.25,25){\makebox(4,2)[l]{PB4}}
\put(0,24){\makebox(1.75,2)[r]{15}}\put(2.25,23){\makebox(4,2)[l]{PB5}}
\put(0,22){\makebox(1.75,2)[r]{16}}\put(2.25,21){\makebox(4,2)[l]{PB6}}
\put(0,20){\makebox(1.75,2)[r]{17}}\put(2.25,19){\makebox(4,2)[l]{PB7}}
\put(0,18){\makebox(1.75,2)[r]{18}}\put(2.25,17){\makebox(4,2)[l]{\overbar{PC}}}
\put(0,16){\makebox(1.75,2)[r]{24}}\put(2.25,15){\makebox(4,2)[l]{\overbar{FLAG}}}
\put(10.25,10){\makebox(2,2)[l]{1}}\put(8,12){\makebox(4,2){$\rm V_{SS}$}}
\put(18.25,14){\makebox(2,2)[l]{19}}\put(14,13){\makebox(3.75,2)[r]{TOD}}
\put(18.25,16){\makebox(2,2)[l]{22}}\put(14,15){\makebox(3.75,2)[r]{R/\overbar{W}}}
\put(18.25,18){\makebox(2,2)[l]{23}}\put(14,17){\makebox(3.75,2)[r]{\overbar{CS}}}
\put(18.25,20){\makebox(2,2)[l]{25}}\put(14,19){\makebox(3.75,2)[r]{$\Phi_2$}}
\put(18.25,22){\makebox(2,2)[l]{26}}\put(14,21){\makebox(3.75,2)[r]{D7}}
\put(18.25,24){\makebox(2,2)[l]{27}}\put(14,23){\makebox(3.75,2)[r]{D6}}
\put(18.25,26){\makebox(2,2)[l]{28}}\put(14,25){\makebox(3.75,2)[r]{D5}}
\put(18.25,28){\makebox(2,2)[l]{29}}\put(14,27){\makebox(3.75,2)[r]{D4}}
\put(18.25,30){\makebox(2,2)[l]{30}}\put(14,29){\makebox(3.75,2)[r]{D3}}
\put(18.25,32){\makebox(2,2)[l]{31}}\put(14,31){\makebox(3.75,2)[r]{D2}}
\put(18.25,34){\makebox(2,2)[l]{32}}\put(14,33){\makebox(3.75,2)[r]{D1}}
\put(18.25,36){\makebox(2,2)[l]{33}}\put(14,35){\makebox(3.75,2)[r]{D0}}
\put(18.25,38){\makebox(2,2)[l]{34}}\put(14,37){\makebox(3.75,2)[r]{\overbar{RESET}}}
\put(18.25,40){\makebox(2,2)[l]{35}}\put(14,39){\makebox(3.75,2)[r]{RS3}}
\put(18.25,42){\makebox(2,2)[l]{36}}\put(14,41){\makebox(3.75,2)[r]{RS2}}
\put(18.25,44){\makebox(2,2)[l]{37}}\put(14,43){\makebox(3.75,2)[r]{RS1}}
\put(18.25,46){\makebox(2,2)[l]{38}}\put(14,45){\makebox(3.75,2)[r]{RS0}}
\put(18.25,48){\makebox(2,2)[l]{21}}\put(14,47){\makebox(3.75,2)[r]{\overbar{IRQ}}}
\put(18.25,50){\makebox(2,2)[l]{39}}\put(14,49){\makebox(3.75,2)[r]{SP}}
\put(18.25,52){\makebox(2,2)[l]{40}}\put(14,51){\makebox(3.75,2)[r]{CNT}}
\put(10.25,54){\makebox(2,2)[l]{20}}\put(8,52){\makebox(4,2){$\rm V_{DD}$}}
%
% The MC 6821 PIA
%
%% The frame and the pins
\thicklines
\put(24,6){\line(0,1){44}\line(1,0){16}\line(0,1){44}}\put(24,50){\line(1,0){16}}
\thinlines
\multiput(20,8)(0,2){2}{\line(1,0){4}}\multiput(23,16)(0,2){16}{\line(1,0){1}}
\multiput(40,8)(0,2){8}{\line(1,0){1}}\multiput(40,26)(0,2){12}{\line(1,0){1}}
\put(32,50){\vector(0,1){2}}
\put(31,4){\line(1,0){1}\line(0,1){2}\line(1,0){1}}
%% The pin numbers and the labels
\put(22,46){\makebox(1.75,2)[r]{36}}\put(24.25,45){\makebox(4,2)[l]{RS0}}
\put(22,44){\makebox(1.75,2)[r]{35}}\put(24.25,43){\makebox(4,2)[l]{RS1}}
\put(22,42){\makebox(1.75,2)[r]{38}}\put(24.25,41){\makebox(4,2)[l]{\overbar{IRQA}}}
\put(22,40){\makebox(1.75,2)[r]{37}}\put(24.25,39){\makebox(4,2)[l]{\overbar{IRQB}}}
\put(22,38){\makebox(1.75,2)[r]{34}}\put(24.25,37){\makebox(4,2)[l]{\overbar{RESET}}}
\put(22,36){\makebox(1.75,2)[r]{33}}\put(24.25,35){\makebox(4,2)[l]{D0}}
\put(22,34){\makebox(1.75,2)[r]{32}}\put(24.25,33){\makebox(4,2)[l]{D1}}
\put(22,32){\makebox(1.75,2)[r]{31}}\put(24.25,31){\makebox(4,2)[l]{D2}}
\put(22,30){\makebox(1.75,2)[r]{30}}\put(24.25,29){\makebox(4,2)[l]{D3}}
\put(22,28){\makebox(1.75,2)[r]{29}}\put(24.25,27){\makebox(4,2)[l]{D4}}
\put(22,26){\makebox(1.75,2)[r]{28}}\put(24.25,25){\makebox(4,2)[l]{D5}}
\put(22,24){\makebox(1.75,2)[r]{27}}\put(24.25,23){\makebox(4,2)[l]{D6}}
\put(22,22){\makebox(1.75,2)[r]{26}}\put(24.25,21){\makebox(4,2)[l]{D7}}
\put(22,20){\makebox(1.75,2)[r]{25}}\put(24.25,19){\makebox(4,2)[l]{E}}
\put(22,18){\makebox(1.75,2)[r]{24}}\put(24.25,17){\makebox(4,2)[l]{CS1}}
\put(22,16){\makebox(1.75,2)[r]{21}}\put(24.25,15){\makebox(4,2)[l]{R/\overbar{W}}}
\put(22,10){\makebox(1.75,2)[r]{22}}\put(24.25,9){\makebox(4,2)[l]{CS0}}
\put(22,8){\makebox(1.75,2)[r]{23}}\put(24.25,7){\makebox(4,2)[l]{\overbar{CS2}}}
\put(32.25,4){\makebox(2,2)[l]{1}}\put(30,6){\makebox(4,2){$\rm V_{SS}$}}
\put(40.25,8){\makebox(2,2)[l]{17}}\put(36,7){\makebox(3.75,2)[r]{PB7}}
\put(40.25,10){\makebox(2,2)[l]{16}}\put(36,9){\makebox(3.75,2)[r]{PB6}}
\put(40.25,12){\makebox(2,2)[l]{13}}\put(36,11){\makebox(3.75,2)[r]{PB3}}
\put(40.25,14){\makebox(2,2)[l]{12}}\put(36,13){\makebox(3.75,2)[r]{PB2}}
\put(40.25,16){\makebox(2,2)[l]{9}}\put(36,15){\makebox(3.75,2)[r]{PA7}}
\put(40.25,18){\makebox(2,2)[l]{8}}\put(36,17){\makebox(3.75,2)[r]{PA6}}
\put(40.25,20){\makebox(2,2)[l]{5}}\put(36,19){\makebox(3.75,2)[r]{PA3}}
\put(40.25,22){\makebox(2,2)[l]{4}}\put(36,21){\makebox(3.75,2)[r]{PA2}}
\put(40.25,26){\makebox(2,2)[l]{19}}\put(36,25){\makebox(3.75,2)[r]{CB2}}
\put(40.25,28){\makebox(2,2)[l]{18}}\put(36,27){\makebox(3.75,2)[r]{CB1}}
\put(40.25,30){\makebox(2,2)[l]{15}}\put(36,29){\makebox(3.75,2)[r]{PB5}}
\put(40.25,32){\makebox(2,2)[l]{14}}\put(36,31){\makebox(3.75,2)[r]{PB4}}
\put(40.25,34){\makebox(2,2)[l]{11}}\put(36,33){\makebox(3.75,2)[r]{PB1}}
\put(40.25,36){\makebox(2,2)[l]{10}}\put(36,35){\makebox(3.75,2)[r]{PB0}}
\put(40.25,38){\makebox(2,2)[l]{7}}\put(36,37){\makebox(3.75,2)[r]{PA5}}
\put(40.25,40){\makebox(2,2)[l]{6}}\put(36,39){\makebox(3.75,2)[r]{PA4}}
\put(40.25,42){\makebox(2,2)[l]{3}}\put(36,41){\makebox(3.75,2)[r]{PA1}}
\put(40.25,44){\makebox(2,2)[l]{2}}\put(36,43){\makebox(3.75,2)[r]{PA0}}
\put(40.25,46){\makebox(2,2)[l]{39}}\put(36,45){\makebox(3.75,2)[r]{CA2}}
\put(40.25,48){\makebox(2,2)[l]{40}}\put(36,47){\makebox(3.75,2)[r]{CA1}}
\put(32.25,50){\makebox(2,2)[l]{20}}\put(30,48){\makebox(4,2){$\rm V_{DD}$}}
%
% The 74LS153
%
%% The frame and the pins
\thicklines
\put(48,28){\line(0,1){18}\line(1,0){8}\line(0,1){18}}\put(48,46){\line(1,0){8}}
\thinlines
\multiput(47,30)(0,2){8}{\line(1,0){1}}
\multiput(56,30)(0,2){2}{\line(1,0){4}}\multiput(56,38)(0,2){4}{\line(1,0){2}}
\put(52,46){\vector(0,1){2}}
\put(51,26.25){\line(1,0){1}\line(0,1){1.75}\line(1,0){1}}
%% The pin numbers and the labels
\put(46,44){\makebox(1.75,2)[r]{6}}\put(48.25,43){\makebox(4,2)[l]{I0a}}
\put(46,42){\makebox(1.75,2)[r]{10}}\put(48.25,41){\makebox(4,2)[l]{I0b}}
\put(46,40){\makebox(1.75,2)[r]{5}}\put(48.25,39){\makebox(4,2)[l]{I1a}}
\put(46,38){\makebox(1.75,2)[r]{11}}\put(48.25,37){\makebox(4,2)[l]{I1b}}
\put(46,36){\makebox(1.75,2)[r]{4}}\put(48.25,35){\makebox(4,2)[l]{I2a}}
\put(46,34){\makebox(1.75,2)[r]{12}}\put(48.25,33){\makebox(4,2)[l]{I2b}}
\put(46,32){\makebox(1.75,2)[r]{3}}\put(48.25,31){\makebox(4,2)[l]{I3a}}
\put(46,30){\makebox(1.75,2)[r]{13}}\put(48.25,29){\makebox(4,2)[l]{I3b}}
\put(52.25,26.25){\makebox(2,2)[l]{8}}\put(51,28){\makebox(2,2){$\rm V_{SS}$}}
\put(56.25,30){\makebox(2,2)[l]{2}}\put(54,29){\makebox(1.75,2)[r]{S1}}
\put(56.25,32){\makebox(2,2)[l]{14}}\put(54,31){\makebox(1.75,2)[r]{S0}}
\put(56.25,38){\makebox(2,2)[l]{15}}\put(54,37){\makebox(1.75,2)[r]{\overbar{Eb}}}
\put(56.25,40){\makebox(2,2)[l]{1}}\put(54,39){\makebox(1.75,2)[r]{\overbar{Ea}}}
\put(56.25,42){\makebox(2,2)[l]{9}}\put(54,41){\makebox(1.75,2)[r]{Zb}}
\put(56.25,44){\makebox(2,2)[l]{7}}\put(54,43){\makebox(1.75,2)[r]{Za}}
\put(52.25,46){\makebox(2,2)[l]{16}}\put(51,44){\makebox(2,2){$\rm V_{DD}$}}
%
% The 74LS151
%
%% The frame and the pins
\thicklines
\put(48,6){\line(0,1){18}\line(1,0){8}\line(0,1){18}}\put(48,24){\line(1,0){8}}
\thinlines
\multiput(47,8)(0,2){8}{\line(1,0){1}}
\multiput(56,8)(0,2){3}{\line(1,0){1}}\multiput(56,18)(0,2){3}{\line(1,0){2}}
\put(52,24){\vector(0,1){2}}
\put(51,4.25){\line(1,0){1}\line(0,1){1.75}\line(1,0){1}}
%% The pin numbers and the labels
\put(46,22){\makebox(1.75,2)[r]{4}}\put(48.25,21){\makebox(4,2)[l]{I0}}
\put(46,20){\makebox(1.75,2)[r]{3}}\put(48.25,19){\makebox(4,2)[l]{I1}}
\put(46,18){\makebox(1.75,2)[r]{2}}\put(48.25,17){\makebox(4,2)[l]{I2}}
\put(46,16){\makebox(1.75,2)[r]{1}}\put(48.25,15){\makebox(4,2)[l]{I3}}
\put(46,14){\makebox(1.75,2)[r]{15}}\put(48.25,13){\makebox(4,2)[l]{I4}}
\put(46,12){\makebox(1.75,2)[r]{14}}\put(48.25,11){\makebox(4,2)[l]{I5}}
\put(46,10){\makebox(1.75,2)[r]{13}}\put(48.25,9){\makebox(4,2)[l]{I6}}
\put(46,8){\makebox(1.75,2)[r]{12}}\put(48.25,7){\makebox(4,2)[l]{I7}}
\put(52.25,4.25){\makebox(2,2)[l]{8}}\put(51,6){\makebox(2,2){$\rm V_{SS}$}}
\put(56.25,8){\makebox(2,2)[l]{7}}\put(54,7){\makebox(1.75,2)[r]{\overbar{E}}}
\put(56.25,10){\makebox(2,2)[l]{6}}\put(54,9){\makebox(1.75,2)[r]{\overbar{Z}}}
\put(56.25,12){\makebox(2,2)[l]{5}}\put(54,11){\makebox(1.75,2)[r]{Z}}
\put(56.25,18){\makebox(2,2)[l]{11}}\put(54,17){\makebox(1.75,2)[r]{S0}}
\put(56.25,20){\makebox(2,2)[l]{10}}\put(54,19){\makebox(1.75,2)[r]{S1}}
\put(56.25,22){\makebox(2,2)[l]{9}}\put(54,21){\makebox(1.75,2)[r]{S2}}
\put(52.25,24){\makebox(2,2)[l]{16}}\put(51,22){\makebox(2,2){$\rm V_{DD}$}}
%
% The hex inverter 74LS05
%
\put(27,54){\line(1,0){1}\line(0,1){2}\line(1,0){1}}\put(28,54){\makebox(2,2)[l]{7}}
\put(24,57){\makebox(8,4){\parbox{10ex}{\center\bf IC4 74LS05}}}
\put(28,60){\vector(0,1){2}\makebox(2,2)[l]{14}}
%% Port I4
\put(37,54){\line(1,0){1}}\put(38,52){\line(0,1){4}\line(1,1){2}}
\put(40.5,54){\circle{1}}\put(41,54){\line(1,0){1}}\put(40,54){\line(-1,1){2}}
\put(37,54){\makebox(.75,2)[r]{9}}\put(41.25,54){\makebox(.75,2)[l]{8}}
%% Port I3
\put(39,57){\line(1,0){1}}\put(40,55){\line(0,1){4}\line(1,1){2}}
\put(42.5,57){\circle{1}}\put(43,57){\line(1,0){1}}\put(42,57){\line(-1,1){2}}
\put(39,57){\makebox(.75,2)[r]{5}}\put(43.25,57){\makebox(.75,2)[l]{6}}
%% Port I5
\put(37,60){\line(1,0){1}}\put(38,58){\line(0,1){4}\line(1,1){2}}
\put(40.5,60){\circle{1}}\put(41,60){\line(1,0){1}}\put(40,60){\line(-1,1){2}}
\put(37,60){\makebox(.75,2)[r]{11}}\put(41.25,60){\makebox(.75,2)[l]{10}}
%% Port I2
\put(39,63){\line(1,0){1}}\put(40,61){\line(0,1){4}\line(1,1){2}}
\put(42.5,63){\circle{1}}\put(43,63){\line(1,0){1}}\put(42,63){\line(-1,1){2}}
\put(39,63){\makebox(.75,2)[r]{3}}\put(43.25,63){\makebox(.75,2)[l]{4}}
%
% Miscellanous parts
%
%% The serial resistor R1 (33R)
\put(57.2,11){\line(0,1){4}\line(1,0){2}\line(0,1){4}}\put(57.2,15){\line(1,0){2}}
\put(59.2,11){\makebox(4,4){\parbox{5ex}{\center\bf R1 33~$\Omega$}}}
%% The pull-up resistor R2 (4k7)
\put(20,56){\line(0,1){4}\line(1,0){2}\line(0,1){4}}
\put(20,60){\line(1,0){1}\vector(0,1){2}\line(1,0){1}}
\put(21,18){\line(0,1){38}\line(1,0){3}}
\put(21,42){\circle{0}}\put(21,42){\line(1,0){3}}
\put(14,57){\makebox(6,4){\parbox{7.5ex}{\center\bf R2 4.7~k$\Omega$}}}
%% The bypass capacitor C1 (100nF)
\put(12,56){\line(1,0){1}\line(0,1){2.5}\line(1,0){1}}
\multiput(11,58.5)(0,1){2}{\line(1,0){4}}
\put(13,59.5){\vector(0,1){2.5}}
\put(6,57){\makebox(6,4){\parbox{7.5ex}{\center\bf C1 100nF}}}
%
% The connections
%
%% Between the CIA and the PIA
\put(18,16){\line(1,0){6}}               % R/-W
\multiput(18,20)(0,2){10}{\line(1,0){6}} % Clock, Data bus and -RESET
\multiput(18,44)(0,2){2}{\line(1,0){6}}  % RS0 and RS1
%% Between the PIA and the 74LS153
\multiput(40,30)(0,2){8}{\line(1,0){8}}
%% Between the PIA and the 74LS151
\multiput(40,8)(0,2){8}{\line(1,0){8}}
%% The pins CA1 and CA2 of the PIA
\put(40,48){\line(1,0){2}}\put(42,48){\circle{0}}
\put(40,46){\line(1,0){2}\line(0,1){5}}\put(35,51){\line(0,1){12}\line(1,0){7}}
\multiput(35,54)(0,3){3}{\circle{0}}
\multiput(35,54)(0,6){2}{\line(1,0){3}}
\multiput(35,57)(0,6){2}{\line(1,0){5}}
\put(42,54){\line(1,0){1}\line(0,-1){10}}\put(43,44){\circle{0}}
\put(44,57){\line(0,-1){15}}\put(44,42){\circle{0}}
\put(42,60){\line(1,0){3}\line(0,-1){22}}\put(45,38){\circle{0}}
\put(44,63){\line(1,0){2}\line(0,-1){27}}\put(46,36){\circle{0}}
%% The 74LS153 and the 74LS151
\put(58,43.2){\framebox(3,1.6){\small B15}}
\put(58,41.2){\framebox(3,1.6){\small B14}}
\put(57,36){\line(1,0){1}\line(0,1){4}\line(1,0){1}}\put(58,38){\circle{0}}
\put(58,22){\line(0,1){8}}\put(58,30){\circle{0}}
\put(60,31.2){\framebox(3,1.6){\small A14}}
\put(58,20){\line(1,0){1}\line(0,1){12}}\put(59,32){\circle{0}}
\put(60,29.2){\framebox(3,1.6){\small A15}}
\put(58,17.2){\framebox(4,1.6){\small\overbar{CAS}}}
\put(57,10){\line(1,0){1.1}\line(0,1){1}}\put(58.1,16){\line(0,-1){1}\line(1,0){.9}}
\put(59,15.2){\framebox(4,1.6){\small MA8}}
\put(57,8){\line(1,0){1}}\put(57,6){\line(1,0){1}\line(0,1){2}\line(1,0){1}}
\put(16,7){\framebox(4,2){\small\overbar{I/O2}}}
\put(17,9.2){\framebox(3,1.6){\small A7}}

\end{picture}
\end{center}
\caption{The schematics diagram of the expansion. See text.}
\label{PIAschematics}
\end{figure}

\begin{figure}
\setlength{\unitlength}{1.5ex}
\begin{center}
\begin{picture}(20,16)(-5,0)
% Caption
\put(-5,16){\makebox(20,2){\bf U13 74LS257A}}
% The Dual-In-Line housing
\thicklines
\put(1,0){\line(1,0){8}}\put(1,0){\line(0,1){16}}
\put(9,0){\line(0,1){16}}\put(1,16){\line(1,0){8}}
\put(5,16){\oval(2,2)[b]}\put(1.5,15.5){\circle{0}}
% The pins
\thinlines
\multiput(0,1)(0,2){8}{\line(1,0){1}}
\multiput(9,1)(0,2){8}{\line(1,0){1}}
% The pin numbers
\put(2,14){\makebox(2,2)[l]{1}}
\put(6,14){\makebox(2,2)[r]{16}}
\put(2,12){\makebox(2,2)[l]{2}}
\put(6,12){\makebox(2,2)[r]{15}}
\put(2,10){\makebox(2,2)[l]{3}}
\put(6,10){\makebox(2,2)[r]{14}}
\put(2,8){\makebox(2,2)[l]{4}}
\put(6,8){\makebox(2,2)[r]{13}}
\put(2,6){\makebox(2,2)[l]{5}}
\put(6,6){\makebox(2,2)[r]{12}}
\put(2,4){\makebox(2,2)[l]{6}}
\put(6,4){\makebox(2,2)[r]{11}}
\put(2,2){\makebox(2,2)[l]{7}}
\put(6,2){\makebox(2,2)[r]{10}}
\put(2,0){\makebox(2,2)[l]{8}}
\put(6,0){\makebox(2,2)[r]{9}}
% The descriptions
\put(-5,14){\makebox(5,2)[r]{\overbar{CAS}}}
\put(10,14){\makebox(5,2)[l]{$\rm V_{DD}$}}
\put(-5,12){\makebox(5,2)[r]{A14}}
\put(10,12){\makebox(5,2)[l]{\overbar{AEC}}}
\put(-5,10){\makebox(5,2)[r]{A6}}
\put(10,10){\makebox(5,2)[l]{A12}}
\put(-5,8){\makebox(5,2)[r]{MA6}}
\put(10,8){\makebox(5,2)[l]{A4}}
\put(-5,6){\makebox(5,2)[r]{A13}}
\put(10,6){\makebox(5,2)[l]{MA4}}
\put(-5,4){\makebox(5,2)[r]{A5}}
\put(10,4){\makebox(5,2)[l]{A15}}
\put(-5,2){\makebox(5,2)[r]{MA5}}
\put(10,2){\makebox(5,2)[l]{A7}}
\put(-5,0){\makebox(5,2)[r]{$\rm V_{SS}$}}
\put(10,0){\makebox(5,2)[l]{MA7}}
\end{picture}
\end{center}
\caption{Pin-out for the multiplexer chip U13}
\label{U13_pins}
\end{figure}

\begin{figure}[hbt]
\setlength{\unitlength}{1.5ex}
\begin{center}
\begin{picture}(52,40)(-3,0)
% Captions
\put(-5,40){\makebox(26,2){\bf MOS~6526~CIA}}
\put(25,40){\makebox(26,2){\bf MC~6821~PIA}}
% The Dual-In-Line housings
\thicklines
\multiput(1,0)(30,0){2}{\line(0,1){40}\line(1,0){14}\line(0,1){40}}
\multiput(1,40)(30,0){2}{\line(1,0){14}}
\multiput(8,40)(30,0){2}{\oval(2,2)[b]}
\multiput(1.5,39.5)(30,0){2}{\circle{0}}
% The pins
\thinlines
\multiput(0,1)(0,2){20}{\line(1,0){1}}
\multiput(15,1)(0,2){20}{\line(1,0){1}}
\multiput(30,1)(0,2){20}{\line(1,0){1}}
\multiput(45,1)(0,2){20}{\line(1,0){1}}
% The pin numbers
\multiput(2,38)(30,0){2}{\makebox(2,2)[l]{1}}
\multiput(2,36)(30,0){2}{\makebox(2,2)[l]{2}}
\multiput(2,34)(30,0){2}{\makebox(2,2)[l]{3}}
\multiput(2,32)(30,0){2}{\makebox(2,2)[l]{4}}
\multiput(2,30)(30,0){2}{\makebox(2,2)[l]{5}}
\multiput(2,28)(30,0){2}{\makebox(2,2)[l]{6}}
\multiput(2,26)(30,0){2}{\makebox(2,2)[l]{7}}
\multiput(2,24)(30,0){2}{\makebox(2,2)[l]{8}}
\multiput(2,22)(30,0){2}{\makebox(2,2)[l]{9}}
\multiput(2,20)(30,0){2}{\makebox(2,2)[l]{10}}
\multiput(2,18)(30,0){2}{\makebox(2,2)[l]{11}}
\multiput(2,16)(30,0){2}{\makebox(2,2)[l]{12}}
\multiput(2,14)(30,0){2}{\makebox(2,2)[l]{13}}
\multiput(2,12)(30,0){2}{\makebox(2,2)[l]{14}}
\multiput(2,10)(30,0){2}{\makebox(2,2)[l]{15}}
\multiput(2,8)(30,0){2}{\makebox(2,2)[l]{16}}
\multiput(2,6)(30,0){2}{\makebox(2,2)[l]{17}}
\multiput(2,4)(30,0){2}{\makebox(2,2)[l]{18}}
\multiput(2,2)(30,0){2}{\makebox(2,2)[l]{19}}
\multiput(2,0)(30,0){2}{\makebox(2,2)[l]{20}}
\multiput(12,0)(30,0){2}{\makebox(2,2)[r]{21}}
\multiput(12,2)(30,0){2}{\makebox(2,2)[r]{22}}
\multiput(12,4)(30,0){2}{\makebox(2,2)[r]{23}}
\multiput(12,6)(30,0){2}{\makebox(2,2)[r]{24}}
\multiput(12,8)(30,0){2}{\makebox(2,2)[r]{25}}
\multiput(12,10)(30,0){2}{\makebox(2,2)[r]{26}}
\multiput(12,12)(30,0){2}{\makebox(2,2)[r]{27}}
\multiput(12,14)(30,0){2}{\makebox(2,2)[r]{28}}
\multiput(12,16)(30,0){2}{\makebox(2,2)[r]{29}}
\multiput(12,18)(30,0){2}{\makebox(2,2)[r]{30}}
\multiput(12,20)(30,0){2}{\makebox(2,2)[r]{31}}
\multiput(12,22)(30,0){2}{\makebox(2,2)[r]{32}}
\multiput(12,24)(30,0){2}{\makebox(2,2)[r]{33}}
\multiput(12,26)(30,0){2}{\makebox(2,2)[r]{34}}
\multiput(12,28)(30,0){2}{\makebox(2,2)[r]{35}}
\multiput(12,30)(30,0){2}{\makebox(2,2)[r]{36}}
\multiput(12,32)(30,0){2}{\makebox(2,2)[r]{37}}
\multiput(12,34)(30,0){2}{\makebox(2,2)[r]{38}}
\multiput(12,36)(30,0){2}{\makebox(2,2)[r]{39}}
\multiput(12,38)(30,0){2}{\makebox(2,2)[r]{40}}
% The descriptions
\multiput(-5,38)(30,0){2}{\makebox(5,2)[r]{$\rm V_{SS}$}}
\multiput(-5,36)(30,0){2}{\makebox(5,2)[r]{PA0}}
\multiput(-5,34)(30,0){2}{\makebox(5,2)[r]{PA1}}
\multiput(-5,32)(30,0){2}{\makebox(5,2)[r]{PA2}}
\multiput(-5,30)(30,0){2}{\makebox(5,2)[r]{PA3}}
\multiput(-5,28)(30,0){2}{\makebox(5,2)[r]{PA4}}
\multiput(-5,26)(30,0){2}{\makebox(5,2)[r]{PA5}}
\multiput(-5,24)(30,0){2}{\makebox(5,2)[r]{PA6}}
\multiput(-5,22)(30,0){2}{\makebox(5,2)[r]{PA7}}
\multiput(-5,20)(30,0){2}{\makebox(5,2)[r]{PB0}}
\multiput(-5,18)(30,0){2}{\makebox(5,2)[r]{PB1}}
\multiput(-5,16)(30,0){2}{\makebox(5,2)[r]{PB2}}
\multiput(-5,14)(30,0){2}{\makebox(5,2)[r]{PB3}}
\multiput(-5,12)(30,0){2}{\makebox(5,2)[r]{PB4}}
\multiput(-5,10)(30,0){2}{\makebox(5,2)[r]{PB5}}
\multiput(-5,8)(30,0){2}{\makebox(5,2)[r]{PB6}}
\multiput(-5,6)(30,0){2}{\makebox(5,2)[r]{PB7}}
\put(-5,4){\makebox(5,2)[r]{\overbar{PC}}}
\put(-5,2){\makebox(5,2)[r]{TOD}}
\put(25,4){\makebox(5,2)[r]{CB1}}
\put(25,2){\makebox(5,2)[r]{CB2}}
\multiput(-5,0)(30,0){2}{\makebox(5,2)[r]{$\rm V_{DD}$}}
\put(16,0){\makebox(5,2)[l]{\overbar{IRQ}}}
\put(16,2){\makebox(5,2)[l]{R/\overbar{W}}}
\put(16,4){\makebox(5,2)[l]{\overbar{CS}}}
\put(16,6){\makebox(5,2)[l]{\overbar{FLAG}}}
\put(16,8){\makebox(5,2)[l]{$\rm \Phi_2$}}
\put(46,0){\makebox(5,2)[l]{R/\overbar{W}}}
\put(46,2){\makebox(5,2)[l]{CS0}}
\put(46,4){\makebox(5,2)[l]{\overbar{CS2}}}
\put(46,6){\makebox(5,2)[l]{CS1}}
\put(46,8){\makebox(5,2)[l]{E}}
\multiput(16,10)(30,0){2}{\makebox(5,2)[l]{D7}}
\multiput(16,12)(30,0){2}{\makebox(5,2)[l]{D6}}
\multiput(16,14)(30,0){2}{\makebox(5,2)[l]{D5}}
\multiput(16,16)(30,0){2}{\makebox(5,2)[l]{D4}}
\multiput(16,18)(30,0){2}{\makebox(5,2)[l]{D3}}
\multiput(16,20)(30,0){2}{\makebox(5,2)[l]{D2}}
\multiput(16,22)(30,0){2}{\makebox(5,2)[l]{D1}}
\multiput(16,24)(30,0){2}{\makebox(5,2)[l]{D0}}
\multiput(16,26)(30,0){2}{\makebox(5,2)[l]{\overbar{RESET}}}
\put(16,28){\makebox(5,2)[l]{RS3}}
\put(16,30){\makebox(5,2)[l]{RS2}}
\put(16,32){\makebox(5,2)[l]{RS1}}
\put(16,34){\makebox(5,2)[l]{RS0}}
\put(16,36){\makebox(5,2)[l]{SP}}
\put(16,38){\makebox(5,2)[l]{CNT}}
\put(46,28){\makebox(5,2)[l]{RS1}}
\put(46,30){\makebox(5,2)[l]{RS0}}
\put(46,32){\makebox(5,2)[l]{\overbar{IRQB}}}
\put(46,34){\makebox(5,2)[l]{\overbar{IRQA}}}
\put(46,36){\makebox(5,2)[l]{CA2}}
\put(46,38){\makebox(5,2)[l]{CA1}}
\end{picture}
\caption{The CIA and the PIA}
\label{CIAPIA}
\end{center}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{|l|l|}
\hline
\multicolumn{2}{|c|}{\bf Electronic Components} \\ \hline
\multicolumn{1}{|c}{Symbol} & \multicolumn{1}{|c|}{Description} \\
\hline
IC1 & MC 6821 \\
IC2 & 74LS153 (or 74LS253) \\
IC3 & 74LS151 (or 74LS251) \\
IC4 & 74LS05 \\
\parbox{0.57in}{\smallskip U9--U12,\\ U21--U24\smallskip}
    & 80256 or compatible \\
C1  & 100 nF polyester capacitor \\
R1  & 33 $\Omega$ resistor \\
R2  & 4.7 k$\Omega$ resistor \\
\hline
\hline
\multicolumn{2}{|c|}{\bf Other Parts} \\ \hline
\multicolumn{1}{|c}{Quantity} & \multicolumn{1}{|c|}{Quality} \\
\hline 
2 pcs     & \parbox{2.3in}{\smallskip
            20-pin through-put connectors
            (halves of piggyback socket)
            \smallskip} \\
1 pc      & \parbox{2.3in}{\smallskip
            40-pin socket (if U2 is not socketed)
            \smallskip} \\
1 pc      & 16-pin socket \\
plenty of & connection wire \\
\hline
\end{tabular}
\end{center}
\caption{Parts list for the expansion}
\end{table}

\subsection{Removing the old memory chips}

First you have to remove the memory chips U9--U12 and U21--U24. If you
look at the mother board from the front of the computer as if you were
typing, the chips are on the front left in two rows of eight chips.
They are of type 4164 (or 3164 or 6665 or 6664 or 8064 or\ldots). You
could install the new chips into sockets, but I thought that it is a
waste of money.

If these memory chips are already on sockets, the most of the work is
done for you. It helps a lot, if you remove the bypass capacitors
before removing the chips. Removing the components is easiest with a
desoldering pump. It becomes even easier, when you first solder the
pins with fresh solder, so that the hartz from it makes the removal of
old solder easier.

Using much power is questionable, as the copper folio comes off the
board in a surprisingly easy way. As usual, I used a screwdriver like
a crowbar, and the through-coppering got lost from several places.
This was not crucial, as those pins were connected only to the down
side of the board. However, three or four routes broke on the top side
also. This made it far more difficult (and slower) to solder the new
chips in, but I succeeded on the first try.

After you have removed the 4164s, you can solder the 16-pin sockets
(or the 41256 memory chips) into their places. You can solder the
capacitors back as well, if you removed them.

\subsection{Adding the new address line}

You must connect the pin~1 of each memory chip (or socket). It is the
extra address line (MA8) to the switcher. The best way is to solder a
Wire-Wrap wire to each contact under the mother board, but any thin
and pliable uni-strand wire should do. The wire does not affect in any
way the computer's operation with 64~kb chips.

After the pins have been connected together, they must be temporarily
connected to +5~V, which is in the pin~8 of the memory chips. Comparing
to TTL chips, the operating voltages are `reversed' in dynamic memories.

Now the new 256~kb memory chips can be installed to the sockets
(preferably right-side forward), and you can try switching the power
on. You do not have to connect anything except the power cable and the
cable to the TV set or monitor. It is a good idea to turn on the
monitor first and let it warm up, so that it will show the picture
from the very beginning.

If the screen shows up normally, you may not (yet) have made any
mistakes. If it does not show up at all, you have to find possible
cut-outs and shorts. Multi-colored `{\tt\verb|@|}'s show up usually
because of too small bypass capacitors. Another cause is that the
pin~1 is not connected to +5~V. In this case the screen may come up
normally, but a little disturbance in the operating voltage locks the
computer up. Now the computer should operate exactly like an
unexpanded C64, so any previously working program should work with it.

\subsection{Prepare for the final step}

Next you remove U13 (74LS257, to the right of the memory chips) and U2
(MOS~6526, near the keyboard connector). Either or both of these chips
may already be on sockets, and you must remove the rest. Reinsert the
chips and check if the machine boots up.

If the computer does not work on first try, remember to disconnect any
cables from it before trying to fix the problem. The soldering iron
may occasionally give little electric pulses to the computer, and this
might burn some expensive chips, especially if the computer is hooked
to a wall outlet or a television set.

When you have completed the preparations, you can start building the
control logic. You could build the whole expansion by piggy-backing
chips, that is, by soldering new chips on the top of old ones, bending
some feet to the side, and connecting messy wires all over your
computer. However, the best way is to put most of the chips on a
daughter board. I used only a small daughter board, and piggy-backed
two or three chips, but you can be wiser and put all new chips on the
daughter board.

My daughter board interfaces the heart of the expansion, MC~6821~PIA,
to the bus of the computer through the pins of U2, the MOS~6526~CIA
near the keyboard connector. The CIA is raised on the board on a
normal socket, whose pins are lenghtened with two through-put socket
halves, so that they can reach the socket on the mother board. I built
the daughter board on an uncoppered prototype board, a plastic board
with holes punched in it at a 1/10 inch grid.

After raising the CIA on the daughter board, it is a very good idea to
insert the board to the socket and check if the machine boots up.
The next step is to add the PIA on the board. The contacts from the
CIA except the operating voltages may be difficult to route. I solved
the problem by putting the wires through the small holes that were
left between the biggy-back socket halves and the down surface of the
daughter board. It was very painful, but the design is very compact.
After soldering all CIA contacts to the PIA, I wired the inverter and
the rest of the chips. To increase reliability, I used thin
multi-strand wire, as uni-strand wire gets easily loose when you push it.

Since I had finished the daughter board, I bent up the pins 2 and 11 of
the U13 multiplexer chip, and connected its pins 1, 2, 10 and 11 to the
daughter board with wires. First I inserted the wires for A14 and A15
directly to the chip socket, but as it turned out to be unreliable, I
located a through-put place for each line, and soldered the wires
there instead.

When you have wired the multiplexer U13, remove the jumper wire
between MA8 and +5~V and connect that address line to the daughter
board. Then connect the PIA's \overbar{CS} line to \overbar{I/O2},
which is in U15's pin~9 (or one of the through-put places along the
trace's path to the cartridge port), and insert the daughter board to
the socket. Switch the power on and pray that your dear computer
works.

If you get only crap consisting of {\tt\verb|@|}'s or some randomly
changing graphics, check that all CIA pins have a good contact to the
piggy-back socket, and that the wires from U13 and its socket are
firmly connected. If it doesn't help, you have to check all daughter
board connections with the continuity tester. Don't panic, you can
ensure that the computer works by connecting the MA8 line back to
+5~V, by bending the U13 lines back down, and by inserting the CIA
directly on the motherboard.

\subsection{Testing}

After you have installed the boards to your machine, it is time to
test the connections. You can connect LED, keyboard and probably disk
drive in addition to the power cable and the TV cable, but do not
fasten the mounting screws yet. If the screen shows up and if the
machine seems to operate, input the following test program:

\begin{quote}
\begin{verbatim}
10 PB=57282
20 POKE PB,255:POKE PB+1,4:POKE PB,255
30 PRINT"PRESS A KEY AFTER THIS HAS DISAPPEARED":
   FOR I=0 TO 3000:NEXT
40 POKE PB,14:WAIT 198,15:GET A$:POKE PB,255
\end{verbatim}
\end{quote}

On the line {\tt 10} a variable {\tt PB} is set up. It is the address
of the peripheral and data direction registers for the 6821 port~B,
and the block selection register of the segments {\tt 2} and {\tt 3}
and the VIC-II.

The line {\tt 20} contains initialization of PIA: the lines PB0--PB7
are set outputs, the data direction register is switched to data
register with `{\tt POKE~PB+1,4}', and the PB lines are set high.

On the line {\tt 40} VIC-II is given block~{\tt 0} ({\tt\$00000}--%
{\tt\$0FFFF}), and then the program waits for a keypress and restores
the block~{\tt F} ({\tt\$30000}--{\tt\$3FFFF}).

If this test program works as expected, the screen will be filled with
`{\tt\verb|@|}'s and other random characters.

At this point, you may want to run the {\tt TEST} program, which is
among the distribution files.\footnote{See Section~\ref{TEST}.}

\section{Using the expansion}
\subsection{The operation of the block switcher}

There are four new micro chips in the expansion. The most important of
them is the PIA chip MC~6821, which holds the values of the block
selections. The PIA has two 8-bit ports set up in the addresses {\tt
57280} and {\tt 57282}. The upper and lower four bits (nybbles) of
each port determine which 16~kB block is mapped to each 16~kB segment
of the processor's address space. IC2 and IC3 participate in forming
the memory block control signals.

There is a chip equivalent to the PIA even in Commodore's own 6500
series, but it is not suitable for this connection, as it is not TTL
compatible. The 6821 from Motorola 6800 series, which contains also
processors reminding those in the CSG\footnote{Commodore Semiconductor
Group; former Mostek or MOS Technologies} 6500 and 8500 series, is bus
compatible and suitable for this purpose.

Commodore~64 asserts the 16 bit addresses to the original 64~kb chips
in two parts. First it asserts the lower eight bits, then the higher
eight. The 256~kb chips require two additional address bits, so the
chips are given nine bits at a time. Due to this address multiplexing,
the block selection bits cannot be directly input to the memory chips,
but they must be lead through the multiplexer circuitry of IC2, IC3 and
U13.

IC4 contributes to the operation during power-up. It ensures that the
C64 gets reasonable memory blocks to its different segments. In the
beginning the segments are filled with four upmost memory blocks.

\subsubsection{PIA's location in address space}

The PIA's data bus and E, \overbar{RESET} and R/\overbar{W} signals have
been connected directly to the 6526 chip. Similarly are the RS0 and the
RS1, which select a PIA register, connected to A0 and A1.

The I/O block decoder (U15) tells us when the second I/O block is
selected. This block resides in the area {\tt\$DF00}--{\tt\$DFFF}. The
signal \overbar{I/O2} is connected to the PIA's chip selection pin
\overbar{CS}, and it forms most of its addressing. The address line A7
limit PIA's area in I/O2 to {\tt\$DF80}--{\tt\$DFFF}, because it will
be tied to the CS pin.

\subsubsection{Block selection}

As the address space has been divided to four segments of 16~kB, the A14
and A15 cannot be lead directly to the memory chips, but they participate
in the block selection. These two address bits determine which of the
four blocks is in use. For each segment, the PIA ports tell which memory
block to map. Original A14 and A15 are connected to IC2 and IC3, which
select the right output lines of PIA. For each 16~kB segment there are 4
output lines which form the block address for the segment.

IC2 selects two lowest bits of the block address and feeds them to the
address multiplexer chip U13 as B14 and B15. They are practically
equivalent to the A14 and A15 signals. After the address bits A0--A7
have been asserted during the first addressing cycle, IC2 asserts B14
and B15 during the second (CAS) cycle.

The 256~kb memory chips still need two extra address bits. The
expansion must multiplex them with IC3, which is a `one-of-eight'
multiplexer. Its eight inputs are tied to the two upmost bits of the
four block addresses. A14 and A15 are connected to the IC3, but it
needs yet another control signal to handle all eight input bits. This
signal is \overbar{CAS}, which controls multiplexing other address
bits (MA0--MA7) as well.

While the \overbar{CAS} signal is low and the memory chips are fed the
lowest bits (A0--A7) of the address, the IC3 selects the third bit of
the block address determined by A14 and A15. This bit is called
address bit A16, and it is asserted to the `extra' address line MA8
simultaneously with the lowmost bits. When \overbar{CAS} is high, the
upper address bits are fed, and IC3 selects the fourth bit of the
block address determined by A14 and A15. It corresponds to the address
bit A17 and is fed through the same MA8 with all the other upmost
bits.

When the video chip accesses the bus, the address and data lines from
the processors are in high-impedance state, driven to logical `{\tt
1}' level with very weak current, so that the video chip can change
their state easily. As the address lines A14 and A15 are not connected
to the VIC-II, they remain as logical `{\tt 1}' whenever the video
chip has the bus. Thus, the switcher logic `thinks' that the address
range {\tt\$C000}--{\tt\$FFFF} is being addressed, and it selects the
block for that segment also for the VIC-II.

The resistor on the MA8 line protects the IC3, because the inputs of
dynamic memories are not fully TTL compatible.

\subsubsection{Startup settings}
\label{InitialState}

In order to enable the operation of the machine, each of the four
segments must be mapped to a unique memory block. The Commodore~64
Kernal tests the lowmost continuous area of writeable memory and would
hang up, if the same block was mapped to both {\tt\$0000} and to
{\tt\$4000}, for instance. Modifying the startup routines would cure
this problem, but in that case the Kernal ROM chip should be changed.

The bootup state can be achieved otherwise. The \overbar{RESET} signal
sets all the PIA port lines to inputs. As input a line has an impedance
of several megaohms. A TTL chip reads such a signal as a logical `{\tt
1}'. IC4 can force four block selection pins (PA0, PA1, PA5 and PB0) low,
so that the memory segments of C64 point to the four upmost memory blocks
in ascending order. The port~A contains the bits {\tt 1101~1100} and the
port~B {\tt 1111~1110}. As the IC4 has open collector outputs, it doesn't
disturb the port's operation when outputting high state. That is why the
initialization routines\footnote{See Section~\ref{MemoryInit}.} write the
value {\tt 52} to the address {\tt 57281}, which forces the IC4 outputs
high by lowering the CA2 line.

\subsection{Segmented memory}

The address space of Commodore~64 consists of four 16~kB segments which
are at the address ranges {\tt\$0000}--{\tt\$3FFF}, {\tt\$4000}--{\tt\$7FFF},
{\tt\$8000}--{\tt\$BFFF} and {\tt\$C000}--{\tt\$FFFF}. An expanded
C64 uses the topmost four 16~kB blocks of the memory after startup. It
considers them as its whole world and does not know anything of the other
memory blocks. Figure~\ref{MemoryMap} describes the situation. A total of
twelve memory blocks are left out of the C64's world.

With expanded memory we can cheat the C64 by writing a suitable number
to a known address, in order to make it consider the lowmost block as
the second segment, for example. Then all operation that the C64 does
at the second segment's area alter in fact the lowmost block, although
the computer has no idea of it. This is the idea behind the whole
expansion circuit.

What is the benefit of it? The second segment (segment~{\tt 1}) is
actually a good example of the function, because it resides in the
middle of the RAM reserved for C64 BASIC programs. If we make a little
C64 BASIC program that holds an array exactly in the third segment, we
can switch another memory block to that area while the program is
running, and we have another 16 kilobytes to expand our table. In this
manner all unused memory blocks ($12 \times 16$ kilobytes) can be
taken in use, and the memory is able to hold enormous arrays, which
can be accessed simply by switching the memory block. See
Example~\ref{BigArray} for an example of this technique.

Another and more useful way to exploit the extra blocks is to use them
as a RAM disk. A RAM disk means that you can copy even a whole disk to
these blocks and consider it as a new disk drive, from which you can load
program and data at a very fast speed. For a RAM disk you need a smart
program that redirects disk commands and executes them on the expanded
memory.\footnote{See Section~\ref{RAMdisk}.}

\subsection{Critical addresses}

The critical addresses of the device are {\tt 57216}--{\tt 57343}
({\tt\$DF80}--{\tt\$DFFF}). There is the PIA chip to which you {\tt
POKE} the values to switch memory blocks. The PIA does not have 128
registers, as one might think. There are sixteen copies of its 4
addresses in that memory area. For instance, the addresses {\tt 57216},
{\tt 57284}, {\tt 57288} and {\tt 57340} are equivalent to each other.

{\tt 57280} is a memory place whose lowmost four bits (bits~0--3, low
nybble) determine, which of the sixteen memory blocks is accessed
through the lowmost segment (segment~{\tt 0}) of Commodore~64. The
upper four bits (bits 4--7, high nybble) specify, which of the blocks
show up at the second segment (segment~{\tt 1}). In a similar manner the
low nybble of the address {\tt 57282} determines which block resides at
segment~{\tt 2}, and the high nybble tells the block addressed via the
upmost segment.

These addresses have even another function. They can act as data
direction registers as well, i.e. tell if the port lines are inputs or
outputs. However, this application uses only some of the PIA's
characteristics. For normal operation, all the port lines should be set
to outputs. The function of these addresses depend on the bit~2 of the
next address. For instance, the function of {\tt 57280} is defined with
the address {\tt 57281}. If you {\tt POKE} there a value with its third
bit set, the values written to {\tt 57280} will go to the data direction
register. Inputs have the corresponding data direction register bits
reset, and outputs have them set. See Tables \ref{DFC0}--\ref{DFC3} for
a complete description of PIA registers.

\pagebreak
\subsection{Initializing the expansion}
\label{MemoryInit}

Before using the expansion memory, you have to first initialize the
PIA. Every time when a \overbar{RESET} is issued, the PIA registers
change to the default state.\footnote{See Section~\ref{InitialState}.}
In the beginning of your program you will initialize the PIA registers
so that the default block division of memory remains:

\medskip
\begin{tt}
\begin{tabular}{l l l}
pia & .equ \$DFC0
\\
\\ & LDA pia+1 & ; Select Peripheral Registers
\\ & ORA \#4
\\ & STA pia+1
\\ & TAX
\\ & LDA pia+3
\\ & ORA \#4
\\ & STA pia+3
\\ & TAY
\\
\\ & LDA \#\$FE & ; Set the default memory block data
\\ & STA pia+2
\\ & LDA \#\$DC
\\ & STA pia
\\
\\ & TXA        & ; Select Data Direction Registers
\\ & AND \#\$FB
\\ & STA pia+1
\\ & TYA
\\ & AND \#\$FB
\\ & STA pia+3
\\
\\ & LDA \#\$FF & ; Set the ports to output
\\ & STA pia
\\ & STA pia+2
\\
\\ & TXA
\\ & AND \#\$C7
\\ & ORA \#\$30 & ; Set CA1 and
\\ & STA pia+1  & ; select Peripheral Registers
\\ & STY pia+3
\end{tabular}
\end{tt}
\medskip

\pagebreak

You may want to use an array instead. That will save both space and
processing time but lose generality. Someone may have CB1 or CB2 in
use,\footnote {See Section~\ref{Expanding}.} and changing all the command
register bits causes side effects on these pins. Anyway, here is a BASIC
example of using an initialization table:

\begin{quote}
\begin{verbatim}
10 PIA=57280
20 FOR I=11 to 1 STEP -1:READ A:POKE PIA+I,A:NEXT
30 DATA 4,254,4,220,0,255,0,255,4,254,52
\end{verbatim}
\end{quote}

Many Commodore~64 games do not like any extra hardware in the area
{\tt\$DE00}--{\tt\$DFFF}, as it is used by many ``freezer'' cartridges
and alike. If you need to use such software with the memory expansion,
you can completely disable the PIA from the address space until a
system \overbar{RESET} occurs. To do this, change the last {\tt DATA}
value on the line {\tt 30} from {\tt 52} to {\tt 53}. By the way, the
expansion can be easily enhanced to be the most powerful freezer
cartridge. See Section \ref{Freezer} if you are interested in this.

\subsection{Programming the PIA in machine language}

Think it in hexadecimal numbers. There are sixteen memory blocks,
numbered from {\tt 0} to {\tt F}. The address {\tt\$DFC0} holds two
hexadecimal digits. The less significant digit, the one at right,
selects the memory block for the segment~{\tt 0} ({\tt\$0000}--%
{\tt\$3FFF}), whereas the other digit is for segment~{\tt 1}. The other
important PIA address, {\tt\$DFC2}, selects the blocks for segments
{\tt 2} and {\tt 3} with is low and high nybble, respectively.

For instance, if you want to switch block~{\tt E} ({\tt\$38000}--%
{\tt\$3BFFF}) to segment~{\tt 1}, initialize the PIA and execute the
following. Note that your program must run outside segment~{\tt 1}
({\tt\$4000}--{\tt\$7FFF}), or otherwise the next instruction will be
fetched from the new block, thus probably crashing the processor.

\medskip
\begin{tt}
\begin{tabular}{l l l}
pia & .equ \$DFC0
\\
\\ & LDA pia & ; Segments 0 and 1
\\ & AND \#\$0F & ; Preserve segment~0
\\ & ORA \#\$E0 & ; Select block~E for segment~1
\\ & STA pia
\end{tabular}
\end{tt}
\medskip

If you used our initialization routine before this, the memory areas
{\tt\$4000}--{\tt\$7FFF} and {\tt\$8000}--{\tt\$BFFF} should now mirror
each other. This is an easy way to peek under ROMs and I/O with a simple
machine language monitor that does not play with the 6510's I/O
registers to switch ROMs and I/O temporarily out.

\subsubsection{An exception: video memory}

As the video chip's address bus is only fourteen bits wide, it can access
only sixteen kilobytes directly. The two additional lines needed to
address 64~kB are provided by the second CIA. Its lines PA1 and PA0 are
the inverse of the VIC-II's address lines VA15 and VA14.

The VIC-II needs another two address lines to see full 256~kB of
memory. The PIA lines PB7 and PB6 (the uppest two bits of {\tt\$DFC2})
serve as VA17 and VA16. So, the VIC-II memory does not necessarily
have to be accessible to 6510, but there is a restriction: As the
block selector for the upmost segment uses the same two lines, both
the VIC block and the block for segment~{\tt 3} cannot be chosen
freely.

For instance, if you want the VIC to `see' its RAM at {\tt\$04000}, the
lines VA17--VA14 must be `{\tt 0001}'. You can select only blocks {\tt
0}--{\tt 3} for segment~{\tt 3} to fulfill this condition. Let's assume
that you want block~{\tt 2} to be mapped there:

\medskip
\begin{tt}
\begin{tabular}{l l l}
cia2 & .equ \$DD00 \\
pia  & .equ \$DFC0
\\
\\ & LDA cia2+1 & ; First set the CIA2 lines
\\ & ORA \#\$03 & ; PA0 and PA1 to output.
\\ & STA cia2+1
\\
\\ & LDA cia2   & ; Then set PA1 and reset PA0.
\\ & AND \#\$FC & ; Remember, the lines VA15 and VA14
\\ & ORA \#\$02 & ; are the inverse of them.
\\ 
\\ & LDA pia+2  & ; Segments 2 and 3
\\ & AND \#\$0F & ; Preserve segment~2
\\ & ORA \#\$20 & ; Select block~2 for segment~3
\\ & STA pia+2
\end{tabular}
\end{tt}
\medskip

If you want the video bank selection to work exactly like in a stock
computer, you have four alternative memory block configurations. The
addresses {\tt\$DFC2} and {\tt\$DFC0} must contain one of the following
bytes: {\tt\$FE} and {\tt\$DC}, {\tt\$BA} and {\tt\$98}, {\tt\$76} and
{\tt\$54}, or {\tt\$32} and {\tt\$10}. You can use the expansion to
debug or examine programs that occupy full 64 kilobytes of normal
memory. When you issue a \overbar{RESET}, the program's memory will
remain totally unaltered, if it is outside the topmost four blocks.
There is no need for a `freezer' cartridge.\footnote{See Section
\ref{Freezer}.}

\begin{table}
\begin{center}
\begin{tabular}{|c|l|}
\hline
\multicolumn{2}{|c|}{\bf Peripheral Register A} \\ 
\multicolumn{2}{|c|}{\em (Peripheral Lines PA7--PA0)} \\ \hline
Bits & Description \\ \hline
7--4 & Block Selection, Segment~{\tt 1} \\
3--0 & Block Selection, Segment~{\tt 0} \\
\hline
\hline
\multicolumn{2}{|c|}{\bf Data Direction Register A} \\ \hline
Bits & Description \\ \hline
7--0 & Data Direction of Peripheral Lines PA7--PA0 \\
& \parbox{4in}{\small\smallskip When a bit is set, its corresponding Port~A 
line is an output. Otherwise it is an input.\smallskip} \\ \hline
\end{tabular}
\end{center}
\caption{The PIA address {\tt\$DFC0} ({\tt 57280})}
\label{DFC0}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|c|c l|}
\hline
\multicolumn{3}{|c|}{\bf Control Register A} \\ \hline
Bit(s) & \multicolumn{2}{l|}{Description} \\ \hline

 7 & \multicolumn{2}{l|}{IRQA1 Interrupt Flag} \\
& \multicolumn{2}{l|}{\parbox{4in}{\small\smallskip
Goes high on active transition of CA1; 
Automatically cleared by MPU read of Peripheral Register~A.
May also be cleared by hardware \overbar{RESET}.\smallskip}} \\ \hline

 6 & \multicolumn{2}{l|}{IRQA2 Interrupt Flag} \\
& \multicolumn{2}{l|}{\parbox{4in}{\small\smallskip When CA2 is an input, 
IRQA2 goes high on active transition of CA2; 
Automatically cleared by MPU read of Peripheral Register~A. 
May also be cleared by hardware \overbar{RESET}.\smallskip}} \\ \hline

 5--3 & \multicolumn{2}{l|}{CA2 Control} \\
& {\tt 00x} & Input, triggered on falling edge \\
& {\tt 01x} & Input, triggered on rising edge \\
&& {\parbox{3.6in}{\small\smallskip
    When {\tt x} is {\tt 1}, \overbar{IRQA} Interrupts 
    by CA2 active transition are enabled.\smallskip}} \\
& {\tt 10x} & Output, Read Strobe for Peripheral Register~A \\
&& {\parbox{3.6in}{\small\smallskip
    CA2 goes low on first high-to-low E transition following a read of
    Peripheral Register~A. When {\tt x} is {\tt 0}, it remains low until
    next active CA1 transition. When {\tt x} is {\tt 1}, CA2 remains low
    for one E cycle.\smallskip}} \\
& {\tt 110} & Reset CA2 \\
& {\tt 111} & Set CA2 \\ \hline

 2 & \multicolumn{2}{l|}{Register in address {\tt\$DFC0}} \\
& {\tt 0} & Data Direction Register \\
& {\tt 1} & Peripheral Register \\ \hline

 1 & \multicolumn{2}{l|}{Determine Active CA1 Transition} \\
& {\tt 0} & IRQA1 set by high-to-low transition on CA1 \\
& {\tt 1} & IRQA1 set by low-to-high transition on CA1 \\ \hline

 0 & \multicolumn{2}{l|}{CA1 Interrupt Request Enable/Disable} \\
& {\tt 0} & Disable \overbar{IRQA} Interrupt by CA1 active transition. \\
& {\tt 1} & Enable \overbar{IRQA} Interrupt by CA1 active transition. \\ \hline
\end{tabular}
\end{center}
\caption{The PIA address {\tt\$DFC1} ({\tt 57281})}
\label{DFC1}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|c|l|}
\hline
\multicolumn{2}{|c|}{\bf Peripheral Register B} \\ 
\multicolumn{2}{|c|}{\em (Peripheral Lines PB7--PB0)} \\ \hline
Bits & Description \\ \hline
7--4 & Block Selection, Segment~{\tt 3} \\
3--0 & Block Selection, Segment~{\tt 2} \\
\hline
\hline
\multicolumn{2}{|c|}{\bf Data Direction Register B} \\ \hline
Bits & Description \\ \hline
7--0 & Data Direction of Peripheral Lines PB7--PB0 \\
& \parbox{4in}{\small\smallskip When a bit is set, its corresponding Port~B 
line is an output. Otherwise it is an input.\smallskip} \\ \hline
\end{tabular}
\end{center}
\caption{The PIA address {\tt\$DFC2} ({\tt 57282})}
\label{DFC2}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|c|c l|}
\hline
\multicolumn{3}{|c|}{\bf Control Register B} \\ \hline
Bit(s) & \multicolumn{2}{l|}{Description} \\ \hline

 7 & \multicolumn{2}{l|}{IRQB1 Interrupt Flag} \\
& \multicolumn{2}{l|}{\parbox{4in}{\small\smallskip
Goes high on active transition of CB1;
Automatically cleared by MPU read of Peripheral Register~B.
May also be cleared by hardware \overbar{RESET}.\smallskip}} \\ \hline

 6 & \multicolumn{2}{l|}{IRQB2 Interrupt Flag} \\
& \multicolumn{2}{l|}{\parbox{4in}{\small\smallskip When CB2 is an input, 
IRQB2 goes high on active transition of CB2; 
Automatically cleared by MPU read of Peripheral Register~B. 
May also be cleared by hardware \overbar{RESET}.\smallskip}} \\ \hline

 5--3 & \multicolumn{2}{l|}{CB2 Control} \\
& {\tt 00x} & Input, triggered on falling edge \\
& {\tt 01x} & Input, triggered on rising edge \\
&& {\parbox{3.6in}{\small\smallskip
    When {\tt x} is {\tt 1}, \overbar{IRQB} Interrupts 
    by CB2 active transition are enabled.\smallskip}} \\
& {\tt 10x} & Output, Read Strobe for Peripheral Register~B \\
&& {\parbox{3.6in}{\small\smallskip
    CB2 goes low on first high-to-low E transition following a read of
    Peripheral Register~B. When {\tt x} is {\tt 0}, it remains low until
    next active CB1 transition. When {\tt x} is {\tt 1}, CB2 remains low
    for one E cycle.\smallskip}} \\
& {\tt 110} & Reset CB2 \\
& {\tt 111} & Set CB2 \\ \hline

 2 & \multicolumn{2}{l|}{Register in address {\tt\$DFC2}} \\
& {\tt 0} & Data Direction Register \\
& {\tt 1} & Peripheral Register \\ \hline

 1 & \multicolumn{2}{l|}{Determine Active CB1 Transition} \\
& {\tt 0} & IRQB1 set by high-to-low transition on CB1 \\
& {\tt 1} & IRQB1 set by low-to-high transition on CB1 \\ \hline

 0 & \multicolumn{2}{l|}{CB1 Interrupt Request Enable/Disable} \\
& {\tt 0} & Disable \overbar{IRQB} Interrupt by CB1 active transition. \\
& {\tt 1} & Enable \overbar{IRQB} Interrupt by CB1 active transition. \\ \hline
\end{tabular}
\end{center}
\caption{The PIA address {\tt\$DFC3} ({\tt 57283})}
\label{DFC3}
\end{table}

\section{Programming the expansion in BASIC}

With BASIC the use of the extra memory is a bit limited. In the upmost
segment (segment~{\tt 3}) there is operating system ROM, under which
you can place different memory blocks, but reading them with BASIC is
naturally impossible. However, in some cases writing data to this
segment partially under Kernal~ROM and I/O area may be a working
solution. The lowmost kilobytes are free RAM, and it can be utilized
by switching memory blocks. But the benefit of the extra memory
decreases, as you can use only the lowmost four kilobytes of each
block.%
\footnote
{
  You can read and write the area {\tt\$C000}--{\tt\$DFFF} of this
  segment using BASIC. Accessing the area {\tt\$D000}--{\tt\$DFFF} 
  without machine language is tricky but possible.
}

The highest segment but one, segment~{\tt 2}, is halfly under BASIC ROM,
and only its lower half can be freely used.%
\footnote
{
  You can always write under ROM (except in the UltiMax game cartridge
  configuration).
}
When utilizing it, you have to take in consideration that those 8
kilobytes can be under a ROM cartridge, if one is connected, or they could
hold some of the variables and tables that are stored in the top of the
BASIC memory. You have to construct your programs so that they do not
collide with the segment's area.

The lowmost segment, segment~{\tt 0}, contains Kernal's and BASIC
interpreter's system variables. Normally you cannot change its contents,
since the operating system would not find its status information. This
can be worked around by copying those vital bytes to the new memory block
and switching the block with a machine language routine.

The only segment that can be wholly used with plain BASIC is the
segment~{\tt 1}, the second one from the bottom ({\tt\$4000}--%
{\tt\$7FFF}). It resides in the middle of the space reserved for BASIC
programs. If you construct your BASIC programs wisely, that is short
enough, and ensure that the information used by BASIC are located
exactly on this area, you can switch the blocks in this segment freely
and exploit all the twelwe extra blocks as a huge data storage.

Example~\ref{BigArray} shows how you can create a table on this area
and hold its data simultaneously in all the extra memory blocks.

\subsection{Processing a huge array}

\label{BigArray}
\begin{quote}
\begin{verbatim}
10 I=0:J=0:K=0:A=0
20 DD=56576:PIA=57280
30 FOR I=11 TO 0 STEP -1:READ A:POKE PIA,A:NEXT
31 DATA 4,254,4,220,0,255,0,255,4,254,52,220
40 K=16384-7:POKE 47,K AND 255:POKE 48,K/256:
   POKE 49,K AND 255:POKE 50,K/256
50 DIM A%(8191)
60 FOR I=0 TO 15:POKE PIA,I*16+12
70 PRINT I":";:FOR J=0 TO 9:PRINT A%(J),:NEXT:PRINT:NEXT
80 POKE PIA,220:END
\end{verbatim}
\end{quote}

The program displays ten first integers of each memory block. The table
it reserves fills the whole segment~{\tt 1}, because each integer
(notice the {\tt\%} sign) takes two bytes and 8192 of them are reserved.
The contents of the table {\tt A\%} can be changed to another memory
block by simply {\tt POKE}ing PIA's corresponding register. On the line
{\tt 40} the table is ensured to start at {\tt\$4000} by changing the
start and end addresses of tables in the addresses {\tt 47}--{\tt 50}.
Saving the name, size and dimensions of the table takes the seven bytes,
which are subtracted from the start address.

Reserving the table to an arbitrary address has its drawbacks. The size
of the program and its variables may not exceed 14 kilobytes so that
they could fit to the memory before the beginning of the table. All
variables must definitely be declared before allocating the table. If
you do not declare them by giving them a value, the interpreter finds
really exotic values for them or transfers the table off its position.

\subsection{Storing graphics}

\begin{quote}
\begin{verbatim}
10 I=0:J=0:A=0:A$=""
20 DD=56576:PIA=57280:V=53248:COLOUR=50176
30 FOR I=11 TO 0 STEP -1:READ A:POKE PIA,A:NEXT
31 DATA 4,254,4,220,0,255,0,255,4,254,52,220
40 POKE V+24,16+8:POKE V+17,59
50 FOR I=0 TO 11:POKE PIA+2,I*16+14:
   POKE DD,PEEK(DD) AND 252 OR (NOT I AND 3)
60 FOR J=0 TO 999:POKE J+COLOUR,3:NEXT
70 GET A$:IF A$="" THEN 70
80 NEXT I
90 POKE PIA+2,254:POKE DD,PEEK(DD) OR 3:
   POKE V+24,23:POKE V+17,27
\end{verbatim}
\end{quote}

The extra memory can be used as a store of high resolution pictures as
well. This program shows all twelve memory areas that could contain
reasonable pictures. The pictures can be created with a BASIC extension
that resides in RAM and saves its graphics under Kernal ROM. In those
memory blocks that contain no pictures, you see random memory contents.

High resolution graphics is enabled on the line {\tt 40}. The beginning
of the line {\tt 50} switches block {\tt I} to the segment~{\tt 3} and
switches the VIC chip to the same memory area. The second {\tt POKE}
statement selects the block for the video chip. `{\tt (NOT I AND 3)}'
filters the extra bits off and inverts the essential ones so that they
can be stored to the lowmost two bits of {\tt\$DD00}. The line {\tt 60}
sets the picture's colour to black-cyan. The next line waits for a
keystroke before showing another picture. After all blocks have been
shown, the original state of the I/O chips will be restored on the line
{\tt 90}.

\section{RAM disk and other programs}

As memory expansions are expensive, programs making use of extra memory
are rare. Besides, different expansions are not compatible with each
other. However, it does not mean that you could not fully utilize the
expansion. The most obvious utilization method is a RAM disk. When using
VC-1541, it is not only luxury but almost vital condition.

Pekka Pessi has made a couple of programs that utilize the expansion.
The software is distributed in two self-extracting archive files ({\tt
SFX}es).

The file {\tt ROS-V1.SFX} (for RAM Operating System) holds the source
code of the RAM disk program, and some miscellanous files. To load the
archive file, use the command ``{\tt LOAD"ROS-V1.SFX",}{\it device\/}''.
Then change a blank disk to the drive before {\tt RUN}ning. The second
archive file, {\tt UTIL256.SFX}, contains the following software:

\subsection{Memory test}
\label{TEST}

The program {\tt TEST} tests the block selection and the whole memory.
If it jams before reporting ``{\tt Test passed}'', something has gone
wrong. Its source code is in the file {\tt TEST.A}, which requires a
library {\tt STRING.A}. I translated the executable to English by
patching the binary file.

\subsection{Poor man's multitasking}
\label{MULTI51200}

With the {\tt MULTI51200} program you can run four different programs.
The program does no multitasking, it only holds four environments in the
memory, each in its own memory block. {\tt MULTI.A} is the source code.
After loading it with ``{\tt LOAD"MULTI51200",{\it device},1}'' and
initializing the BASIC pointers with ``{\tt NEW}'', you can switch the
environments with ``{\tt SYS51200,{\it f},{\it b\/}}''. The parameter
{\it f\/} is a flag determining if the current block should be copied to
the destination block ({\tt 0}) or not ({\tt 1}). The {\it b} selects
the destination block ({\tt 0}--{\tt 3}). The initial block is {\tt 3}.

\subsection{Machine language monitor}

If you don't like to switch the memory blocks manually in your favourite
machine language monitor, the {\tt MON256} utility is for you. The memory
is again divided to four 64~kB blocks, numbered from 0 to 3. The commands
are explained in Table~\ref{MON256}.

\begin{table}
\begin{center}
\begin{tabular}{|l|l|}
\hline
{\parbox{1.6in}{\smallskip 
{\tt a \it nnnn cmd\/} or \\ {\tt .\ \it nnnn cmd}\smallskip}} &
{\parbox{2.8in}{\smallskip
Assembles instruction {\it cmd\/} to memory address {\it nnnn}.\smallskip}}
\\\hline
{\tt b \it bb ff} &
{\parbox{2.8in}{\smallskip Selects a block. The {\it bb\/} holds the
block number, and {\it ff\/} is a flag. If it is {\tt 1}, it directs all
memory accessing to RAM. If it is {\tt 0}, you can access the ROMs and
I/O.\smallskip}}
\\\hline
{\tt c \it hhhh iiii jjjj} &
{\parbox{2.8in}{\smallskip Compares the memory area {\it hhhh}--{\it iiii\/}
with the area beginning from {\it jjjj}.\smallskip}}
\\\hline
{{\tt d} [{\it hhhh\/} [{\it iiii\/}]]} & {\parbox{2.8in}{\smallskip 
Disassembles memory.\smallskip}}
\\\hline
{\tt f \it hhhh iiii nn} &
{\parbox{2.8in}{\smallskip Fills the memory between {\it hhhh\/} and
{\it iiii\/} with the byte pattern {\it nn}.\smallskip}}
\\\hline
{{\tt g} [{\it hhhh\/}]} &
{\parbox{2.8in}{\smallskip Executes program until a {\tt BRK} 
is encountered.\smallskip}}
\\\hline
{\parbox{1.6in}{\smallskip{\tt h \it hhhh iiii nn mm\ldots} or \\
{\tt h {\it hhhh iiii\/} '{\it text}}\smallskip}} &
{\parbox{2.8in}{\smallskip Hunts the memory area {\it hhhh}--{\it iiii\/}
for the byte sequence {\it nn mm\ldots} or for {\it text}.\smallskip}}
\\\hline
{{\tt j} [{\it hhhh\/}]} & {\parbox{2.8in}{\smallskip 
Calls a subroutine.\smallskip}}
\\\hline
{{\tt l "{\it filename\/}"}[{\tt ,}{\it n\/}]} &
{\parbox{2.8in}{\smallskip Loads a program.
Default device number is 8.\smallskip}}
\\\hline
{{\tt m} [{\it hhhh\/} [{\it iiii\/}]]} & {\parbox{2.8in}{\smallskip
Hexadecimal dump of memory.\smallskip}}
\\\hline
{\tt >\it hhhh nn mm\ldots} & {\parbox{2.8in}{\smallskip
Stores bytes in memory.\smallskip}}
\\\hline
{\tt r} & {\parbox{2.8in}{\smallskip Dumps the registers 
(for {\tt g} and {\tt j}).\smallskip}}
\\\hline
{\tt ;} & {\parbox{2.8in}{\smallskip Modifies the register values.\smallskip}}
\\\hline
{\tt s "{\it filename\/}",{\it n},{\it hhhh},{\it jjjj}} &
{\parbox{2.8in}{\smallskip
Saves the memory area {\it hhhh}--{\it jjjj}.\smallskip}}
\\\hline
{\tt t \it hhhh iiii jjjj} & 
{\parbox{2.8in}{\smallskip Copies the memory area {\it hhhh}--{\it iiii\/} to
{\it jjjj}.\smallskip}}
\\\hline
{{\tt v "{\it filename\/}"}[{\tt ,}{\it n\/}]} & {\parbox{2.8in}{\smallskip
Verifies a program. Default device number is 8.\smallskip}}
\\\hline
{\tt x} & {\parbox{2.8in}{\smallskip Exits the monitor.\smallskip}}
\\\hline
{{\tt \verb|@|} [{\it command\/}]} &
{\parbox{2.8in}{\smallskip Sends {\it command\/} to device~8. If it
begins with {\tt\$}, the disk directory will be read. If no command
is given, the disk drive's status will be displayed.\smallskip}}
\\\hline
\end{tabular}
\end{center}
\caption{Commands for the {\tt MON256} utility}
\label{MON256}
\end{table}

The source code for the monitor is split in the files {\tt MON.A}, 
{\tt CONSOLE.A}, {\tt COM.A}, {\tt ROUTINES.A} and {\tt TABELS.A}.

\subsection{RAM disk}
\label{RAMdisk}

The most important utility is a RAM disk program, which occupies about 9
kilobytes of memory. It transfers Kernal and BASIC interpreter to RAM
and patches the serial bus routines. The actual program is in the area
{\tt\$00800}--{\tt\$03FFF}.

It emulates all VC-1541 functions except relative files. For example,
the commands {\tt U1}, {\tt U2}, {\tt B-A} etc. work. {\tt UI+} and {\tt
UI-} make no difference. The program also detects some fast loaders and
works with them installed.

The loader is called {\tt RAM DISC}, and the patched Kernal is in {\tt
RAM.K}. You need only patches to the low-level serial bus routines, so
you may want to restore the original colors and keyboard definitions. To
minimize incompatibility problems, you should replace the ROM chip that
holds the BASIC and Kernal ROMs with an EPROM containing the patched
Kernal. The RAM disk routines are in {\tt RAM.C}.

\subsubsection{Disk copiers}

The program {\tt RAM DISC COPY} copies a regular 1541 disk to RAM. It
utilizes the slow {\tt U1} command, and it is included as an example
only. The source code {\tt DUP.A} exposes the RAM disk's storage format.

A faster and more useful tool is {\tt FDUPLICATE}. Using it, you can
copy a regular disk to the RAM disk or vice versa. You can make multiple
copies of a disk easily. This program's fast transfer routines are
designed for PAL systems, and the utility cannot be used in NTSC
machines without little modification. Its source code is in the two
files {\tt S/SUCK} and {\tt S/DSUCK}.

\section{Enhancing the expansion} 
\label{Expanding}

There are a couple of unused contacts in the PIA. In addition to that,
two 7405 ports are not connected. The extra PIA lines include an input,
CB1, an input/output line CB2, and the Interrupt Request line
\overbar{IRQB}.

If you connect the \overbar{IRQB} line to the \overbar{IRQ} or
\overbar{NMI} input of your system, you can have one or two new interrupt
sources, useful for interfacing your custom hardware. And if you are
running out of User Port pins, the lines CB1 and CB2 can save you from
designing an I/O cartridge. Besides, you can use the \overbar{IRQB} as an
output if you wire the CB1 line to something that you can control with
software, CA2 for instance. Just remember to add a pull-up resistor to
the \overbar{IRQB} line if necessary.

\subsection{Built-in freezer}
\label{Freezer}

For the Commodore 64, there are several `freezer' cartridges that let the
user to halt theoretically any program (game) to alter it (make the
player immortal), or more often merely to make a `back-up copy' of it.
Alas, anything cannot be frozen with these cartridges. If the programmer
of the game is clever enough to inhibit IRQ and NMI interrupts in his
program, and if the code runs at the area {\tt\$0000}--{\tt\$0FFF}, no
external cartridge will be able to halt it without asserting the
\overbar{RESET} signal, which would lose most status information of the
computer.

This freezer expansion will let you to replace the program's memory with
previously initialized RAM by pressing the Restore key. If the NMI
interrupts are disabled, freezing will be done with the BRK instruction.
As the circuit forces the \overbar{HIRAM} line to logical zero, the interrupt
vectors will always be fetched from RAM. All of the freezer software can
be stored to RAM, so it is easy to change, and no EPROM programming
devices are needed. Another advantage is that the freezer software may
freely use 128 kilobytes of memory, and there are 64 kilobytes of
working storage, way more than in the best freezer cartridges.

For this expansion, you need a double ON--OFF or ON--ON switch, four
1N4148 diodes and two $\rm 10~k\Omega$ resistors. First do some
preparations. Break the connection between the PIA's \overbar{RESET}
input (pin~34) and the system \overbar{RESET}, and replace it with a
diode with the marked end towards the system bus, so that the pass
direction is from the PIA to the system \overbar{RESET}. Then you have to
solder a pull-up resistor between the PIA's \overbar{RESET} line and the
+5~V power outlet. Locate the U8 chip (7406) on the motherboard and
desolder its pin~6. Solder a diode between the motherboard connection and
the pin with the mark pointing to the chip. Finally, solder the other
pull-up resistor between the U8's pin 6 and +5~V. After these
modifications, the PIA should continue to reset normally, and the Restore
key should remain functional.

Now you can mount the switch to the system. If you have an ON--ON switch,
hold it in your hand in such an angle that you see two rows of three
pins. Solder two diodes from the right-hand contacts of the switch to the
U8's pin~6, with the mark pointing to the U8. Solder the PIA's
\overbar{RESET} line (pin~34) to either middle contact of the switch, or
to either free contact if you have an ON--OFF switch. Finally, mount the
\overbar{HIRAM} line, which is on the 6510's pin~28, to the remaining middle
contact.

The switch affects in the operation of the Restore key. When it is open,
the Restore key operates normally. When the switch is closed, the Restore
key also resets the PIA, switching the default memory blocks in, and
forces the \overbar{HIRAM} line low, so that the interrupt vectors will
always be fetched from RAM. The idea of the expansion is that the program
runs in some other memory blocks, say {\tt 3}--{\tt 0}, with the PIA totally
disabled from the address space. The default memory blocks ({\tt\$F}--%
{\tt\$C}) will be initialized mostly with null bytes, which is the opcode
of the {\tt BRK} instruction. You also need the freezer interrupt vectors
({\tt\$FFFA}--{\tt\$FFFF}) and a small interrupt handler that stores the
processor registers and switches the main freezer program into the address
space.

If you want to freeze hanged programs, too, you can do it without losing
the state of the I/O chips. By using a custom Kernal ROM, you could even
store all 6510 registers except the Program Counter. You just have to be
able to reset the 6510 without resetting the rest of the chips. To do
this, desolder the \overbar{RESET} signal, pin~40 on the 6510. Connect a
1N4148 diode between the system \overbar{RESET} signal and the 6510, with
the mark pointing away from the processor. Add a pull-up resistor to the
signal, and a switch between the logical ground and the signal.

Now, whenever you push the switch, only the 6510 will be reset. You
should then use the Autostart code ({\tt\$C3 \$C2 \$CD \$38 \$30} at
{\tt\$8004}--{\tt\$8008}), and the Kernal will jump to the vector
{\tt(\$8000)}. Unfortunately it will destroy all registers except the
{\tt Y} register when searching for that code. You could make a slight
modification to the ROM that first saves all registers on some memory
area, like somewhere in {\tt\$90}--{\tt\$FF}. There are some {\tt\$AA}
bytes in the Kernal ROM that you can take into use. Just relocate the
\overbar{RESET} vector ({\tt\$FFFC}) to your routine, and remember to
jump to {\tt\$FCE2} at end.

Alas, I just have invented a software hack that cannot be frozen with
this circuit. If a program runs on the I/O area ({\tt\$DE00}--{\tt\$DFFF}
except the range where the PIA is mapped to while the I/O is switched on)
and has disabled the NMI interrupts, the program will continue running
even if you have activated the freezer and hit the Restore key. Should
you ever encounter this type of a software hack, you can use a triple
switch and add the \overbar{LORAM} signal (6510's pin~29) to one extra
contact. Connect the remaining contact to the U8's pin~6 through a diode
with the mark pointing to the U8. This will disable the I/O area for the
time the Restore signal is active, so the processor can fetch a {\tt BRK}
from the memory underneath, and will always freeze correctly.

I haven't completed the freezer expansion yet, as the daughter-board
in my faithful C64 stopped working when I opened the cover to start
the surgery operation. My first attempt of rebuilding it did not
succeed, and now I am in Germany, more than one megameter away from
the computer. When returning to Finland in August 1994, the freezer
expansion will be one of my first projects I am going to finish.%
\footnote
{
  So I thought at that time---as of December 1999, I have neither
  fixed that particular C64 nor completed the freezer expansion.
  Besides, the expansion would not have much advantage over freezer
  cartridges or the features present in some emulators.
}

Naturally you also need a program to utilize the freezer circuitry. You
don't need to code so much, only the routine to jump back to the freezed
program and the routine that saves all registers upon freezing need to be
written from scratch. You can patch existing machine language monitors,
sprite editors and utilities like that, only the data fetch and data
store subroutines must be rewritten. Developing the freezer software is
very simple, since you can access the frozen program through a 16~kB
window, and you can use the Kernal routines all the time.

\subsection{New operating system}

I had purchased a PC board that allows you to choose
between the Kernal~ROM and a custom 8~kB EPROM (2764). I never
added a fastloader or other useful routines to the Kernal, since I
should have deleted some routines, i.e. the Datassette and RS-232
handling.

But if you had more ROM, you could keep your new Kernal fully
compatible with the old Kernal while adding new features to it.
A 32~kB EPROM would easily hold the RAM disk routines, the disk copier
and routines for adequately fast loading and saving. Still you would
have plenty of space for controlling your own expansions, like a
IEEE-488 interface or a SCSI bus.

\begin{figure}[hbt]
\setlength{\unitlength}{1.5ex}
\begin{center}
\begin{picture}(53,30)(-5,0)
% Caption
\put(-5,28){\makebox(26,2){\bf 2364}}
% The Dual-In-Line housing
\thicklines
\put(1,4){\line(1,0){14}}\put(1,4){\line(0,1){24}}
\put(15,4){\line(0,1){24}}\put(1,28){\line(1,0){14}}
\put(8,28){\oval(2,2)[b]}
\put(1.5,27.5){\circle{0}}
% The pins
\thinlines
\multiput(0,5)(0,2){12}{\line(1,0){1}}
\multiput(15,5)(0,2){12}{\line(1,0){1}}
% The pin numbers
\put(2,26){\makebox(2,2)[l]{1}}\put(12,26){\makebox(2,2)[r]{24}}
\put(2,24){\makebox(2,2)[l]{2}}\put(12,24){\makebox(2,2)[r]{23}}
\put(2,22){\makebox(2,2)[l]{3}}\put(12,22){\makebox(2,2)[r]{22}}
\put(2,20){\makebox(2,2)[l]{4}}\put(12,20){\makebox(2,2)[r]{21}}
\put(2,18){\makebox(2,2)[l]{5}}\put(12,18){\makebox(2,2)[r]{20}}
\put(2,16){\makebox(2,2)[l]{6}}\put(12,16){\makebox(2,2)[r]{19}}
\put(2,14){\makebox(2,2)[l]{7}}\put(12,14){\makebox(2,2)[r]{18}}
\put(2,12){\makebox(2,2)[l]{8}}\put(12,12){\makebox(2,2)[r]{17}}
\put(2,10){\makebox(2,2)[l]{9}}\put(12,10){\makebox(2,2)[r]{16}}
\put(2,8){\makebox(2,2)[l]{10}}\put(12,8){\makebox(2,2)[r]{15}}
\put(2,6){\makebox(2,2)[l]{11}}\put(12,6){\makebox(2,2)[r]{14}}
\put(2,4){\makebox(2,2)[l]{12}}\put(12,4){\makebox(2,2)[r]{13}}
% The descriptions
\put(-5,26){\makebox(5,2)[r]{A7}}\put(16,26){\makebox(5,2)[l]{$\rm V_{CC}$}}
\put(-5,24){\makebox(5,2)[r]{A6}}\put(16,24){\makebox(5,2)[l]{A8}}
\put(-5,22){\makebox(5,2)[r]{A5}}\put(16,22){\makebox(5,2)[l]{A9}}
\put(-5,20){\makebox(5,2)[r]{A4}}\put(16,20){\makebox(5,2)[l]{A12}}
\put(-5,18){\makebox(5,2)[r]{A3}}\put(16,18){\makebox(5,2)[l]{\overbar{CS1}}}
\put(-5,16){\makebox(5,2)[r]{A2}}\put(16,16){\makebox(5,2)[l]{A10}}
\put(-5,14){\makebox(5,2)[r]{A1}}\put(16,14){\makebox(5,2)[l]{A11}}
\put(-5,12){\makebox(5,2)[r]{A0}}\put(16,12){\makebox(5,2)[l]{D7}}
\put(-5,10){\makebox(5,2)[r]{D0}}\put(16,10){\makebox(5,2)[l]{D6}}
\put(-5,8){\makebox(5,2)[r]{D1}}\put(16,8){\makebox(5,2)[l]{D5}}
\put(-5,6){\makebox(5,2)[r]{D2}}\put(16,6){\makebox(5,2)[l]{D4}}
\put(-5,4){\makebox(5,2)[r]{GND}}\put(16,4){\makebox(5,2)[l]{D3}}
%
% Caption
\put(22,28){\makebox(26,2){\bf 27256}}
% The Dual-In-Line housing
\thicklines
\put(28,0){\line(1,0){14}}\put(28,0){\line(0,1){28}}
\put(42,0){\line(0,1){28}}\put(28,28){\line(1,0){14}}
\put(35,28){\oval(2,2)[b]}
\put(28.5,27.5){\circle{0}}
% The pins
\thinlines
\multiput(27,1)(0,2){14}{\line(1,0){1}}
\multiput(42,1)(0,2){14}{\line(1,0){1}}
% The pin numbers
\put(29,26){\makebox(2,2)[l]{1}}\put(39,26){\makebox(2,2)[r]{28}}
\put(29,24){\makebox(2,2)[l]{2}}\put(39,24){\makebox(2,2)[r]{27}}
\put(29,22){\makebox(2,2)[l]{3}}\put(39,22){\makebox(2,2)[r]{26}}
\put(29,20){\makebox(2,2)[l]{4}}\put(39,20){\makebox(2,2)[r]{25}}
\put(29,18){\makebox(2,2)[l]{5}}\put(39,18){\makebox(2,2)[r]{24}}
\put(29,16){\makebox(2,2)[l]{6}}\put(39,16){\makebox(2,2)[r]{23}}
\put(29,14){\makebox(2,2)[l]{7}}\put(39,14){\makebox(2,2)[r]{22}}
\put(29,12){\makebox(2,2)[l]{8}}\put(39,12){\makebox(2,2)[r]{21}}
\put(29,10){\makebox(2,2)[l]{9}}\put(39,10){\makebox(2,2)[r]{20}}
\put(29,8){\makebox(2,2)[l]{10}}\put(39,8){\makebox(2,2)[r]{19}}
\put(29,6){\makebox(2,2)[l]{11}}\put(39,6){\makebox(2,2)[r]{18}}
\put(29,4){\makebox(2,2)[l]{12}}\put(39,4){\makebox(2,2)[r]{17}}
\put(29,2){\makebox(2,2)[l]{13}}\put(39,2){\makebox(2,2)[r]{16}}
\put(29,0){\makebox(2,2)[l]{14}}\put(39,0){\makebox(2,2)[r]{15}}
% The descriptions
\put(22,26){\makebox(5,2)[r]{$\rm V_{PP}$}}\put(43,26){\makebox(5,2)[l]{$\rm V_{CC}$}}
\put(22,24){\makebox(5,2)[r]{A12}}\put(43,24){\makebox(5,2)[l]{A14}}
\put(22,22){\makebox(5,2)[r]{A7}}\put(43,22){\makebox(5,2)[l]{A13}}
\put(22,20){\makebox(5,2)[r]{A6}}\put(43,20){\makebox(5,2)[l]{A8}}
\put(22,18){\makebox(5,2)[r]{A5}}\put(43,18){\makebox(5,2)[l]{A9}}
\put(22,16){\makebox(5,2)[r]{A4}}\put(43,16){\makebox(5,2)[l]{A11}}
\put(22,14){\makebox(5,2)[r]{A3}}\put(43,14){\makebox(5,2)[l]{\overbar{OE}}}
\put(22,12){\makebox(5,2)[r]{A2}}\put(43,12){\makebox(5,2)[l]{A10}}
\put(22,10){\makebox(5,2)[r]{A1}}\put(43,10){\makebox(5,2)[l]{\overbar{CE}}}
\put(22,8){\makebox(5,2)[r]{A0}}\put(43,8){\makebox(5,2)[l]{D7}}
\put(22,6){\makebox(5,2)[r]{D0}}\put(43,6){\makebox(5,2)[l]{D6}}
\put(22,4){\makebox(5,2)[r]{D1}}\put(43,4){\makebox(5,2)[l]{D5}}
\put(22,2){\makebox(5,2)[r]{D2}}\put(43,2){\makebox(5,2)[l]{D4}}
\put(22,0){\makebox(5,2)[r]{GND}}\put(43,0){\makebox(5,2)[l]{D3}}
%
\end{picture}
\caption{The Read-Only Memory Chips 2364 and 27256}
\label{KernalROMs}
\end{center}
\end{figure}

Figure~\ref{KernalROMs} shows the pinouts for the original Kernal~ROM (2364)
and the replacement chip (27256). Connect the address lines A0--A12,
the data bus (D0--D7) and the power supply lines ($\rm V_{CC}$ and GND)
together, and connect $\rm V_{PP}$ to $\rm V_{CC}$.

The signals \overbar{CS}, \overbar{CE} and \overbar{OE} are for chip
selection. Connect \overbar{CE} and \overbar{OE} together, and add
$4.7~{\rm k\Omega}$ resistors between both chips' VCC and chip
selection lines. Then add a ON-ON switch between 2364's \overbar{CS},
27256's \overbar{CE} and \overbar{OE}, and the \overbar{KERNAL} line
that comes from the motherboard originally to 2364's \overbar{CS} pin.

Now you have only the lines A14 and A13 left. PIA's CB2 can control
one of them, but what about the other? No problem, the \overbar{IRQB}
line can be used as an output if the CB1 is connected to CA2 or CB2.
Add $4.7~{\rm k\Omega}$ pull-up resistors from CB2 and \overbar{IRQB}
to +5~V, and lead the signals to the EPROM's free address lines.

Now those A14 and A13 lines are high upon start-up, and the computer
will see the EPROM area {\tt\$6000}--{\tt\$7FFF} instead of the
original Kernal~ROM, if the switch is in correct position. That part
of the EPROM should initialize the PIA. Note that altering the CB2 or
the \overbar{IRQB} lines immediately causes a jump to another EPROM
bank.

\end{document}
