In
order to further justify the choice of this processor, we must
remember that we are building an embedded system. In this case
it is prudent to ask ourselves exactly how much computational power we
need. A 2MHz 8bit CPU is more than sufficient for this
task.
Architecture The
NMOS 6502 is an 8bit processor. It contains two index/general
purpose registers, called X and Y, which are 8bit. The results
of mathematical and logical operations are written to the
accumulator which is also 8bit (though a ninth 'carry' bit is
available). The program counter (PC) is 16bit which means
it can address 65,536 memory locations (64K). Page Zero (the first
256 bytes of memory; &0000-&00FF
) are
used in a special 'efficient' addressing mode, this behaves
like regular addressing but is faster. Indirect addressing
uses base addresses held in Page Zero. Page One
(&0100-&01FF
) is the hardware stack. The 6502 provides
a stack of 256 bytes. While this may seen utterly pathetic,
remember this processor predates the horrible stack abuses
where you, for example, assemble code on the stack. The 6502
stack is a true stack, a dumping ground for registers and
status. Assuming all registers are saved in an interrupt,
our stack needs per interrupt would be only six bytes (PC,
PSR, X, Y, A) and you can thus hold 42 levels of interrupt in
our 'piddly' stack. The final six bytes of the memory map
(&FFFA-&FFFF
) hold the addresses for the three
hardware vectors - namely NMI (Non-Maskable Interrupt, unused
in Amélie), RESET, and IRQ (Interrupt
ReQuest).
As can be seen from the memory map, this dictates how we lay out
our addressing. RAM must be at the lower addresses
and the firmware (ROM, EPROM, FlashROM, etc) must
be at the
higher addresses. It makes sense to place the memory-mapped I/O in
between.
Limitations The 6502 is not without its
limitations, and later versions of the processor have made
attempts to remove such limitations. For example the 65C02
allows you to directly stack and unstack the X and Y
registers. In the NMOS version they must be transferred into
the accumulator first. The 65CE02 takes things further with
the addition of a new Z register. We will, though, be
sticking with the original NMOS version of the processor.
It isn't perfect, but it isn't broken. Again, I refer
you to http://www.6502.org/
for documentation on the 65xx
family.
Interrupt
latency One of the particularly good
features of the 6502 is the interrupt latency. This
is the time duration between an interrupt occurring and the
interrupt handler being called. On the 6502, the interrupt
system is extremely quick:
-interrupt happens-
<vector called> ; 8 cycles
PHA ; 3 cycles
TXA ; 2 cycles
PHA ; 3 cycles
TYA ; 2 cycles
PHA ; 3 cycles
Here the interrupt has been called,
PC and PSR stacked, and then (thanks to us) all of the
registers are also stacked. If we add another two cycles for
allowing the current instruction to finish prior to the
interrupt call, then it can be seen that our interrupt handler
can be entered with full status saved in only 21 cycles. If we
were to only use A and X, we could cut out five cycles. If we
were to perform a BIT
test against devices first, we could respond to an individual
interrupt in around 15 cycles.
Returning from interrupt is performed using:
PLA ; 4 cycles
TAY ; 2 cycles
PLA ; 4 cycles
TAX ; 2 cycles
PLA ; 4 cycles
CLI ; 2 cycles
RTI ; 6 cycles
This adds up to twenty four cycles for a full interrupt
return, including restoring all
registers.
What about the
Z80? In comparing the 6502's interrupt
latency against other processors, we can run into problems
with devices such as the Z80 which talk about "machine
cycles", as opposed to plain clock ticks. If we assume that a
"T cycle" is a clock tick, it can be seen that the interrupt
call is about 15 cycles . It takes 11 to 15 cycles to push a
register, 10 to 14 to pull it, and 14 to return from
interrupt. I don't know what registers or status (if any) the
Z80 saved upon responding to an interrupt. Thus, a simple IRQ
and return with nothing else in between takes 29 cycles, more
than the 6502. While typical Z80s are available in 4,6,8MHz
versions, I should point out that the 6502 (in its CMOS
incarnation) is available as a 10MHz part. The 6502
always wins here.
What about the
8088?
While the 8088 has a plus in it's 1Mb
addressing range (even with the segmentation issues), shall we
score it less because of the requirement of a 33% duty cycle
clock, or because the data bus is shared with the lower eight
bits of the address bus? Simply the interrupt request
instruction (IRET), which
restores the flags and the CS:IP
address to return to, takes 44 cycles! It takes 15
cycles to push a register word onto the stack, and 12 to
restore it. This is not an efficient processor,
though thankfully things are much improved in later incarnations.
It isn't beyond the realms of imagination that the interrupt
setup and exit sequences alone can run into cycle counts
measured in hundreds!
Why is interrupt latency so
important? On the face of it, it isn't.
If Amélie is controlling a central heating system,
for example, then a few microseconds here or there won't make
any difference. Analogue switch thermostats are often so vague
that it wouldn't matter much if the heat was turned off
seconds (or even an entire minute) after the thermostat
interrupt. Oh the other hand, if Amélie is applied
as a robot and she's hurtling across a table, then the very
last thing you want is a long lag when a sensor says
"woah! we're all outta table here guys... guys!?! hello!?!?!". The 6502
could have done something about it before the Z80. And, well,
we'd crash and burn before the 8088 noticed...
More advanced
processors As mentioned at the top
of the page, we have to take a quick reality check and
assess what we expect. Sure, it'd be fun to code up an ARM7500FE to
control the heating, but it'd be criminal - such
power and potential doing diddly-squat. For those of you
who like pictures, consider the 6502 against an 80486 (which
is a pretty large lump of ceramic):
The size of the processor may not put you off.
After all, you can always use a bigger circuit board, right?
Well, let's look underneath:
One would be a nightmare to attach to a circuitboard,
and one wouldn't. Guess. Sadly, the ARM7500FE - being a surface-mount kind
of chip - is far worse. There are about eight billion
legs per square inch...
But we need not worry. The
6502 provides all that we require...
Other 6502
systems
For computers we have an
impressive range - all of Acorn's early machines from the
System 5s and the Atoms through to the Master 128 were based
upon the 6502. Acorn didn't have great success in America,
their main competitor was Apple's Apple II which - surprise
surprise - was also based upon the 6502. The Oric was a 6502
machine, as was the well-known Commadore PET. And that's just
for starters!
Ironically, until the rise of
the 'XT' with MS-DOS, no home computers used the 8086/8088 -
nobody took them seriously!
In the embedded market, we
are in an era predating PICs and heavily customised
microcontrollers. A number of devices were actually mini
computers running fixed software, much like Amélie. The Ringdale Megabuffer II
was based upon the Z80, while the picture below is of a CASE
modem that I salvaged from a dump many years ago. It is a 6502
design with 2K RAM and (I think) 8K of EPROM, plus
interfacing.
The 6502 turned up in other
places - a Prestel/Viewdata box. If you happen to be a
certain Gareth Babb that ran a viewdata BBS with a name like
CCL4 (?), then you might smile to know that I once called your
service back in 1992 using an actual viewdata
set-top-box!
|