Beruflich Dokumente
Kultur Dokumente
Display
A-LEVEL ELECTRONICS PROJECT
Dharmesh Malam
AUGUST 2002
www.dharmeshmalam.com
2 Memory Addressed Display
CONTENTS
Summary ................................................................................................................................................................. 5
Specification ........................................................................................................................................................... 6
General ............................................................................................................................................................... 6
Systems .............................................................................................................................................................. 6
Microprocessor .............................................................................................................................................. 6
Display ............................................................................................................................................................ 8
Sound ............................................................................................................................................................. 9
Input............................................................................................................................................................... 9
System Design....................................................................................................................................................... 10
Microprocessor ................................................................................................................................................ 10
General......................................................................................................................................................... 10
Clock ............................................................................................................................................................. 12
Ram .............................................................................................................................................................. 14
IO.................................................................................................................................................................. 16
Display .............................................................................................................................................................. 29
LEDs .............................................................................................................................................................. 29
PCB ................................................................................................................................................................... 37
Construction ................................................................................................................................................ 39
Pros .............................................................................................................................................................. 42
Cons ............................................................................................................................................................. 42
Pro ................................................................................................................................................................ 43
Cons ............................................................................................................................................................. 43
Pros .............................................................................................................................................................. 44
Cons ............................................................................................................................................................. 44
Software ............................................................................................................................................................... 45
Summary .......................................................................................................................................................... 45
Memory ............................................................................................................................................................ 45
Pixels to Pictures.............................................................................................................................................. 49
Diary...................................................................................................................................................................... 54
4 Memory Addressed Display
Resources.............................................................................................................................................................. 56
Evaluation ............................................................................................................................................................. 57
Acknowledgements .............................................................................................................................................. 58
General ............................................................................................................................................................. 58
Books ................................................................................................................................................................ 58
Internet ............................................................................................................................................................ 58
Other ................................................................................................................................................................ 58
Software ........................................................................................................................................................... 58
Appendix ............................................................................................................................................................... 59
Hardware ......................................................................................................................................................... 59
Software........................................................................................................................................................... 60
5 Memory Addressed Display
SUMMARY
The aim of this project was to design and construct a memory mapped display system, consisting of a
large matrix of 860 LEDs. This is multiplexed and constantly refreshed by a hardware driver, which in turn is
under control and refreshed by a Z80 based microprocessor system. The display is completely general and ab-
stracted to software as a range in memory, which is ‘drawn’ to. This is then outputted to the hardware display
driver which outputs to the display LEDs. Both input ports are connect to control pads which each have eight
push buttons, and are used to interface with the system. The software creates a menu, which allows selection
of programs. A screensaver and sound test program was coded. A simple sound system was also connected
and allows basic noises.
The aim was fully satisfied by the finished project, which showed reliable operation.
6 Memory Addressed Display
SPECIFICATION
GENERAL
The project must be built on a breadboard and a PCB using standard analogue and digital components, such as
74xx, 40xx, Z80, etc, but no use of ‘all in one’ systems.
The project must be completed in three weeks within the feasibility of the equipment requirements.
The system will allow execution of different programs from a menu displayed. There will be a ‘Screen Saver’
program which scrolls user inputted text, at random points across the screen. There should be an introductory
screen.
A ‘Sound Test’ program should also be coded, which should create different sounds depending on which but-
ton is pressed on the pad.
SYSTEMS
MICROPROCESSOR
o A Zilog Z80 based microprocessor system will be constructed on a breadboard. The Z80 will be clocked at
4-MHz from a crystal oscillator.
o The Z80 will interface with four 8-bit output ports, and 2 * 8-bit input ports, i.e. 32-bits of output and
16-bits of input.
o The output ports will be addressed as output port 0, port 1, port 2, and port 3. Additional IO, and address
decode hardware consisting of a 74LS42, and OR Gates will insure that the right port is selected. The out-
put ports are 74LS374 8-bit D-type flip-flops, which are clocked at specific times by the IO decode hard-
ware. This latches the data bus, and therefore has the correct bits as output.
o The input ports will be addressed input port 0 and input port 1. Each is 8-bits wide, and consists of
74LS244 8-bit tristates. Their output enables (/OE) pins are pulsed low by the IO decode hardware, ‘letting
through’ the output from the control pads to the data bus. This is then read by the Z80.
o The Z80 has a ROM and a RAM. The ROM is actually a RAM, but backed by a battery, so its contents are
not lost. It is wired as a standard 2k x 8 EPROM (2716). This memory is pre-built on a mini PCB and fits into
a ZIF socket. It can easily be removed, and inserted into a ‘program loader’ which allows editing of its
contents. The contents are the opcodes and data that the Z80 executes, and processes. This ZIF arrange-
ment allows quick editing and testing.
o The Z80 is also equipped with a 6116 2Kx8 RAM. This gives 2 Kilobytes of memory locations for temporary
storage. The control pins are connected to the memory decoder, which enables the ROM or RAM de-
pending on need.
o The memory decoder consists of a 74LS42, which has pins /MEMRQ, /RD and A11 from the Z80 connected
to inputs C, B, A respectively. Outputs /0 and /1 are connected to /OE pins on the ROM and RAM, so that
when /MEMRQ, /RD, and A11 are all low, /OE to the ROM goes low, thus reading from ROM. When A11 is
high, /OE on the RAM goes low, hence reading from the RAM. /MEMRQ is also connected to the chip en-
able pin (/CE) on the RAM, and /WR from the Z80 is connected to /WR on the RAM. This ensures that
7 Memory Addressed Display
o A relaxation oscillator creates an uneven clock at about 100Hz which is shaped to be mainly high, but
spikes instantly to low by a 4017, is connect to the Maskable Interrupt (/INT) pin on the Z80. This means
the interrupt service routine is called every one hundredth of a second. This routine contains housekeep-
ing functions, such as checking for a pause, and resetting the sound system.
DISPLAY DRIVER
o This sub-system has the role of outputting the right data, from the frame-buffer RAM, to the multiplexer
system. It must also reset the right counters and multiplexers at the right time, and generate the Master
Display Clock. It is refreshed by the Z80 microprocessor system when needed by software, i.e. under pro-
grammer control. This also implements double buffering, which is described later.
o This sub-system is the go between the Z80 and the display. This system controls and outputs to the display
static frames, one bit per LED at any time. To make the simplest scene, like a flashing dot, requires the Z80
to refresh the RAM. This refreshing is controlled by output ports 0, 1, and 2.
o Two 6116 RAMs are connected in parallel, with address and control lines (/WR, /OE) commoned. The data
lines are parallel, so a 16 x 2k RAM is created. The 16 parallel data lines are connected to the display bus,
which in turn are connected to output ports 0 and 1, and also the row tristates. The display bus is either
allowing data from the Z80 to be written to the frame buffer RAM, or allowing data from this RAM to be
outputted to the row tristates on the PCB.
o The address lines on the 6116 RAM are commoned and connected to a 4024 7-bit binary counter. Address
pins A0 to A6 on the RAMs are connected to Q0 to Q6 on 4024. A7 to A10 are connected to 0V. This gives
128 (2^7) memory locations of which 56 are needed. 56 because the display is multiplexed 16 LEDs (half a
row) at a time, and there are 28 rows, therefore 56 (2 * 28) separate 16-bit wide locations are needed.
This is because there is a one to one mapping between bits in the frame-buffer RAM and LEDs on the on
the display.
o The 4024 is an asynchronous binary counter, which here is configured to count from 0000000B to
1110000B, i.e. 0 to 56. It is reset on 56 by a triple input AND gate (74LS11) connected to Q6, Q5, and Q4.
We can clearly see from the binary representation of 56 (1110000B) why this works, as the most signifi-
cant bits only go high on 56. The output of the AND gate is fed through an OR gate (74LS32) to the reset
pin on the 4024. The other input to the OR gate is connected to a pin on output port 3. This is needed by
the refresh routine, as discussed later. The 4024 is clocked by the Master Display Clock (MDC), through an
OR gate (74LS32). The other input is used by the Z80 to refresh the frame buffer. This arrangement of the
4024 makes the RAM output the memory locations 0 to 55 continuously, which are dots seen by the dis-
play.
o The Master Display Clock (MDC) is what clocks the 4024, column multiplexer and the row tristates. This
ensures that the whole display is in sync, as 56 separate clock cycles are needed to display one frame, and
over 50 frames a second are needed display a flicker free image. The MDC consist of a 555 timer circuit
configured to operate at around 3 KHz, as 56 * 50 gives 2800. The two resistors, Ra, and Rb, where Rb is a
5K potentiometer allowing fine tuning of the display clock to give best performance. The enable pin on
the 555 is connected to a pin on output port, which is used by the refresh routine (called OUTRAM).
8 Memory Addressed Display
DISPLAY MULTIPLEXER
o The display and its associated multiplexing system are built on a double sided PCB. The multiplexing sys-
tems are divided into two parts. They are the row tristates which energize 16-LEDs at a time, the same
width at the display bus, and the column multiplexer which energies row after row, from top to bottom.
Since each row has 30 LEDs, and the display bus is 16-bits wide, two energizes are needed to display one
row. I.e. the first 16 LEDs are energized first and then the last 14 are.
o The row tristates consists of 30 tristates on 4 74LS240 chips. Each chip contains 8 inverting three-state
buffers, all connected to one active low output enable (/OE). Thus the first two 74LS240 have their /OE
pins commoned, and the second two have their /OE pins commoned. The four chips contain 32 tristates,
but there are only 30 LEDs per row, so the last 2 tristates on the fourth chip are not needed. The outputs
of the tristates are all connected through PNP emitter followers to the cathodes of the display LEDs. Thus
the first tristate is connected to 28 LED cathodes, as the display is 30x28. The 16 parallel inputs of the first
16 tristates are connected to the display bus, as are the 16 parallel inputs of the last 16 tristates. The 2
commoned output enables are connected to output 1, and output 2 of a 4017, which is configured to re-
set on 3. The 4017 is a decoded decade counter, and is clocked by the MDC. This means on the first cycle
of the MDC, output 1 goes high, while the other outputs are low. This enables the first 2 74LS240s, and
disables the other 2. On the next cycle, the opposite occurs, and on the next, it resets. There is also a
manual reset, which is connected to output port 3, allowing the microprocessor to reset it.
o The display reset pin is what clocks the column multiplexer, as it goes high every 2 cycles of the MDC, and
as the next row must be selected. This system consists of 2 analogue switches configured as a multi-
plexer. Each multiplexer has 16 outputs, and there are 28 rows so the last 4 outputs on the second multi-
plexer are not needed. A 4024, 7-bit binary counter, is configured to count from 0 to 28, (0000000B, to
0011100B). This is done by resetting through a triple AND gate, which has outputs C, D, and E of the 4024
as inputs. The 4067 have four inputs, forming a 4-bit binary number. Both 4067s have the inputs com-
moned and connected to the Least Significant Bits of the 4024 counter. To select the right multiplexer,
the /EN pin on the first 4067 is connected to output E on the counter, and a NOTted E is connected to /EN
on the second multiplexer. There is also a manual reset, which is connected to output port 3, so the mi-
croprocessor can reset it.
DISPLAY
o The display consists of 24 * 17.3 mm 5x7 dot matrix displays. There are arranged in a 6 x 4 grid. There-
fore we have 6 * 5 dots on the x-axis, and 4 * 7 dots on the y-axis. Hence 30 x 28 dots giving a total of 840
dots. This gives the display a high pixel density.
o Each 5x7 dot matrix display has all its anodes and all its cathodes connected. Every display has its cath-
odes connected to the cathodes of the display above and below it, and its anodes connected to the dis-
play left and right of it. This tiling results in one large 30 x 28 display. Since the displays have equal bor-
ders on each side, the geometry of the display is not distorted.
o This resultant display is driven through PNP emitter followers for the columns, and NPN emitter followers
for the rows. The PNPs are connected to the row tristates, and the NPNs are connected to the column
multiplexer. The PNPs are ZTX550 Bipolar transistors, with a base resistor or 3R9, same as the NPNs which
are ZTX 455s. Both are in an ELINE package, and can source over an amp.
9 Memory Addressed Display
o The emitters in the NPN are connected to their very own power supply. This means the 5V power supply
to the logic is not overloaded and individual adjustment of the brightness can be done.
o A LM317 voltage regulator circuit is used, with de-spiking on the input by a 0.1uF capacitor, and smooth-
ing on the output by a 220uF capacitor. The adjust is controlled by a 10k potentiometer connected to a
knob. This allows adjustment of the voltage, hence the brightness. The input voltage can be varied from
4V to 20V, depending on availability. Even very high voltages, such as 30V, will not damage the display as
the voltage regulator ‘burns’ this off as heat, which is dissipated through a heat sink. The smoothing en-
sures that if suddenly all the LEDs come on, there is enough instantaneous current to light them brightly.
SOUND
o This system allows various sounds to be created when needed in software. A 555 timer clocks a 74LS93
binary counter. This gives us various frequencies. Three different frequencies, plus one at total 5V are put
into tristates. The outputs of the tristates are commoned, and connected to a pizeo buzzer. The 4 input
enables are connected to the first four outputs of output port 3. Different combinations of the output will
create different sounds.
INPUT
o 2 pads made of 8 push-switches are used to interface with the system. They are made on a small PCB.
They connect to the input ports, and usually give a low. The resort to a high when a button is pressed.
10 Memory Addressed Display
SYSTEM DESIGN
MICROPROCESSOR
GENERAL
The Z80 is an 8-bit CISC CPU which can interface with a variety of memories, input and output de-
vices. In the design of this project, a system with 4 output ports and 2 input ports was needed. A 2KB ROM
and a 2KB RAM was also used.
The Z80 has two sets of 6 8-bit general purpose registers, two sets of accumulator and flag registers,
as well as 2 index registers, and other special purpose registers. This is summarised in figure 1 below.
This large register file is used thoroughly in the software, and so is the feature of combining two 8-bit
registers to form a 16-bit register. These registers and the vast instruction set give the programmer the ability
to write complex programs especially if written in assembler as opposed to machine code. The ZIF socket used
to interface the ROM allows quick changes, but the program loader can be tedious to use.
11 Memory Addressed Display
The above diagram shows the pins on the Z80. Address lines A0-A11 were used to access the memo-
ries and address the ports. Pins A12-A15 are not used. Data lines D0-D7 form the data bus which is linked to
the ROM, RAM and the input and output ports.
/CLK was connected to a crystal oscillator circuit shown below in figure 3, which oscillates at 4MHz.
Such a high clock is needed to make sure that the very complex blitting operation (drawing to memory) occurs
instantly with respect to display driver.
The CPU bus control pin /BUSRQ is pulled high as it is not needed. CPU control lines /WAIT and /NMI,
the non maskable interrupt, are pulled high. /RESET is connect to a RC de-bounced switch with also pulses high
on power up to reset the CPU. The maskable interrupt /INT, is connected to a shaped clock, which spikes to
low.
System control pins /MREQ, /IORQ, /WR, /RW all feed the memory and IO decode circuits described
below. /M1, /RFSH, /HALT, and /BUSACK are all disconnected as they are not needed.
12 Memory Addressed Display
CLOCK
The above diagram shows the series resonant crystal oscillator circuit used to clock the Z80. The cir-
cuit is also designed to use the fundamental frequency of the crystal, which here is 4 MHz. The inverter per-
forms a 180-degree phase shift in a series resonant oscillator circuit. The 330 Ohm resistors provide the nega-
tive feedback to bias the inverter in their linear region. The crystal provides a very accurate clock. This allows
accurate estimations of the time taken to execute instructions and a list of the T-states (clock cycles, needed
by each instruction is given in the appendix. Also it means routines are executed extremely fast allowing very
complex routine to be written.
Originally the circuit was built as above, but the Z80 would not clock from it. Testing with a frequency
counter showed it was oscillating at 4MHz. Further testing with an oscilloscope showed the waveform was not
clean enough. This was corrected by sticking a Schmitt trigger (74LS14) on the output. This buffered and
sharpened up the signal.
For testing and construction of the Z80 CPU, a 60 KHz relaxation oscillator was used. This had to be
replaced with a crystal as 60 KHz was to slow and it would not scale over a few hundred kilohertz.
13 Memory Addressed Display
A NOR relaxation oscillator creates the clock signal to /INT. The relaxation oscillator creates a pulse
at about 100Hz. This is used to clock a 4017 decoded decade counter which is configured to reset at 9. The
reset signal is fed into a Schmitt inverter, which is then fed into the /INT pin. This means we get a pulse shape
and so the interrupt service routine is triggered every 100th of a second. Originally a clock which had about
equal mark space was fed in. This was discovered to not be satisfactory as since the Z80 is being clocked at a
high speed the interrupt service routine was being executed extremely fast. This meant that the routine was
finished before the clock could go low again triggering the interrupt again. This happens a few hundred times
before the clock goes high. So instead of triggering the interrupt once, it is triggered half the time the Z80 does
anything. This is inefficient and hence the spiking solution above was used. Note the interrupt service routine
is triggered at best once and at worst a few times.
14 Memory Addressed Display
RAM
The Z80 was equipped with a non-volatile RAM, wired to behave as a ROM, which had 2K locations, as
well as a 6116 2k x 8 RAM. Memory decode circuitry was used to interface the memories to the Z80. We can
see a block diagram in figure 5 below which shows the memory decode and IO refresh circuitry.
15 Memory Addressed Display
16 Memory Addressed Display
Address pins A0 to A10 are connected to A0 to A10 on the ROM and RAM. Data lines D0 to D7 are
connect to D0 - D7 on the ROM and RAM. The memory decode circuit shown above is used. The 74LS24 is used
to enable the right component.
This means when the Z80 wants to read RAM or ROM, /MREQ and /RD go low. A11 is then used to
select the ROM or RAM. Therefore addresses 0H to 800H are ROM, as 2^11 = 2048 = 800h, and 800h to 1000h
are RAM.
/WR is connected to /WR on the RAM, and /MREQ is also connected to /CE, (chip enable). This
means when the CPU wants to write to RAM, /MREQ and /WR goes low, thus selecting the RAM.
IO
Figure 4 also shows IO decode circuit. The Z80 puts a binary code on its address bus corresponding to
which port it wants to talk to. It also puts /IORQ low, when IO operations are needed, and /RD or /WR low
depending on weather it want to read the input port, or write to the output port. The IO decode circuitry
works all this out and enables the right port.
17 Memory Addressed Display
A 74LS42 is again used, with /IOREQ going into input D, and A0, A1, A2 going into inputs A, B, C on
the 74LS42 respectively. This gives 2^3 =8 possible input and output ports. The outputs /0 - /3 go into an OR
gate, which has its other input as either /WR or /RD depending weather this is an input or output port. This
makes sure the right port is selected
/IORQ A2 A1 A0 | /0 /1 /2 /3
1 X X X 1 1 1 1
0 0 0 0 0 1 1 1
0 0 0 1 1 0 1 1
0 0 1 0 1 1 0 1
0 0 1 1 1 1 1 0
Because of the OR gates, if /0 is low, and /RD is low then input port 0 is selected. If /WR was low then
output port 0 would be selected, etc.
This IO decode circuitry gives us 2 inputs ports and 4 output ports, with which the rest of the system is
controlled.
18 Memory Addressed Display
HUMAN INTERFACE
CONTROL PAD
The control pads are the human interface to the system. The microprocessor reads them and uses
them to select and control what is happening in the program. Each one is simply 8 push switches which are
normally pulled low, but go high when pushed. They are constructed on a PCB, using 1K resistors. Each switch
is connected to an 8-bit wide input port. Therefore if no switches are pressed then, all input lines are low, and
if one is pressed, then the corresponding line goes high. The software checks which bit is high or low and does
the corresponding action.
19 Memory Addressed Display
The above diagram shows the circuit used. It was constructed on PCB, shown in the photo below.
There are two pads for a maximum of 2 users.
Originally the switches were not de-bounced. This gave huge problems when testing the software.
Because the CPU polls the input port to see if any bit is high, and the CPU is running at a very high clock speed,
every press would trigger the CPU hundreds of times. This made using it impossible.
There were too problems, first is the bouncing of the switch, when it closes and opens, which may
trigger the CPU a few times, instead of once. The debouncing is normally solved by using a RC network. This
was tried but it did not work as there is also another problem, the very high clock speed. The switch is proba-
bly pressed down for a hundredth of a second, but the input port is polled, maybe a thousand times a second.
This means, the first high triggers the action, then a few microseconds later the action is finished, and the
software looks at the input port again. But the switch is still pressed, therefore the action happens again. So
the end result is that the action occurs a few hundred times, when the user expects it to occur once.
Therefore even though the switch is de-bounced, the RC discharge still triggers the action a few hun-
dred times. To solve this infuriating problem in hardware was nearly impossible. A software solution was
needed.
At first it was wrongly assumed that there was only a denouncing problem, therefore software
de-bouncer was created. The CPU would poll the input port until a bit went high, it would then wait a few mil-
liseconds, and then check if the port was still high, if it was then the action was committed. This de-bounced
the switch, but it still did not work. This was when the other problem was discovered. The solution was to do
the action on the very first high, but then wait for a few tenths of a second until the end of the action and the
return to polling the port. This solved both problems in one go and all in software.
20 Memory Addressed Display
DISPLAY DRIVER
VIDEO RAM
The diagram above shows the display driver. At its heart are 2 * 6116 RAMs wired up to give a 16 x 2k
RAM. It is connected to a 4024 binary counter configured to counter from 0 to 56, reset and then restart. The
16 parallel data lines are connected to the display bus, which is then connected to the row tristates, and out-
put ports 0 and 1. The whole system is controlled by output port 2.
21 Memory Addressed Display
In normal mode, the MDC is enabled, output port 0 and 1 are disabled, and the RAMs are put into
read mode (/WR = high, /RD = low). This make the system output 56 separate 16-bit wide chunks of data
synchronised with the master display clock. The multiplexer circuitry on the PCB decodes this and puts the
right data to the display.
Port 2 is used to control this system. The RAMs contain the data with which display is multiplexed
with. So at address 0000000, there is 16 bits of data, which correspond to the first 16 LEDs on row 1. Address
0000001, has the data for the next 14 LEDs on row 1, the next address has the data for the first 16 LEDs on row
2, and so on until address 55. These can only contain static data, i.e. not moving. To change something, or to
actually put anything in the RAMs, they need to be refreshed with the internal video RAM. To do this the
OUTRAM routine is called. This routine first stops the MDC, by outputting a low on port 2, output pin 1. This
freezes the display. It then resets the 4024 which increments the RAM, by pulsing pin 3. This makes the RAM
be on address 0. Also the /RD goes high, so nothing is outputted, and /EN2 goes high, which disconnects the
column multiplexers so the display is disabled. It then loads the data for the first 16-LEDS, on row 1 to ports 0
and 1, which are on the display bus, hence connected to the data lines on the rams. It then puts a low to /OE
on ports 0 and 1. This means the data for address 0 is on the bus. This is written in by pulsing /WR. So now the
data for the first 16 LEDs have been written in. The clock to the 4024 is pulsed, making the RAMs point to ad-
dress 1. The whole process is repeated until all 112 bytes have been loaded into the RAMs. Then it resets the
4024 and the column and row multiplexers so everything is on the first address. The output enables on ports 0
and 1 are made high, so the display bus is not connected to the ports. /RD is made low now, the MDC is en-
abled and /EN2 goes low enabling the display. This puts the system back into normal mode, but with a com-
pletely refreshed frame buffer.
This sequence of events has to occur every time something changes on the screen, i.e. something
moves or flashes. It also has to be unnoticeable, hence the need for a very fast clock. If there was a slower
clock the display would go blank when the ram is refreshed, but with a 4MHz clock the process is invisible. This
is crucial because it allows very smooth movement with no artefacts.
22 Memory Addressed Display
23 Memory Addressed Display
24 Memory Addressed Display
1. Stop MDC (EN on 555 goes low) and disable display (/EN2 goes high).
The speed of the MDC is crucial for the display. If it is too slow then the multiplexing is visible and the
screen flickers. If it is too fast the system can not keep up and therefore the screen loses synchronization. This
leads to ghosting. To fine tune this frequency, two 10k potentiometers replaced the Ra and Rb resistors on the
555 timer allowing the frequency to be tuned.
ROW TRISTATES
The above diagram shows the row tristate system which is what feeds the LED rows through transis-
25 Memory Addressed Display
tor drivers. It is constructed on a PCB as seen in the photo. It is inputted by the display bus from the PCB. The
74240 are inverting tristates. They invert because otherwise a low on the display bus would light a LED up as
the cathodes are connected to the row tristates. Because they invert, a high on the display bus will light up a
led. This is done purely to make the software easier to write.
Two 74LS240s are connected to form two pairs of 16 tristates which can be enabled alternatively. This
is done by the 4017, which is clocked by the MDC (master display clock). The transistor NOT gates are needed
because the 74240 have active low enables. The 4017 either enables the first two 74240s or the last two. This
means that the display bus is connected to either the first 16 LEDs, or the last 14 LEDs. This arrangement is
clocked by the MDC, so on every increment of the RAMs, the active pair changes. There is also a manual reset,
which is needed by the OUTRAM routine. The divided clock goes to the column multiplexer which energizes
the next column every time the 4017 resets. This ensures that the right 16 LEDs are always lit, in synchronisa-
tion with the video RAMs.
With the above arrangement there were ghosting problems due to the switching occurring too slow
which respect to the RAMs. This meant data for the first 16 LEDs were showing up on the next 14. This was
found to be the fault of the transistor NOT gates due to them not switching cleanly enough. A simple change in
the circuitry solved the problem. The diagram below shows the difference
Figure 8
Figure 9
26 Memory Addressed Display
We can see the transistor NOT gates have been removed, and the lines have simply been swapped
around. This is the equivalent of inverting them, as the 4017 only counts to 2, then resets. The repair work can
be seen in the photo below.
COLUMN MULTIPLEXER
In the above diagram we can see the column multiplexer, whose job is to energise row after row, and
27 Memory Addressed Display
reset keeping synchronisation with the master display clock. After a full reset the first pulse energises row one,
because the 4024 outputs 0000000B. Since the 4 least significant bits are connected to the inputs on the 4067
multiplexer, both select their first output Q1. But since output Q4 on the 4024 is low, then the first 4067 is
enabled and the second one is disabled.
The 4067 is a analogue switch which connects the selected output to input W. Here W is connected to
5V, so the outputs Q0 - Q15 are either disconnected, or connected to 5V, when selected via a 4-bit binary
code. There is a 200R resistance between W and Qx which is part of base resister to the NPN transistors.
The 4024 binary counter is designed to reset on 28, as this is how many rows there are. This done by a
triple AND gate on a 7411 (28 = 11100B) therefore the AND is connected to Q4, Q3, Q2. An OR gate is used,
with the input connected to port 2, this allows the CPU to reset the multiplexer, needed by the OUTRAM rou-
tine.
/EN2 is used to disable both multiplexers, and hence the display, it is normally low but goes high
when the video ram is being refreshed.
The MDC, divided by two, is used to clock the 4027 binary counter. Therefore a new row is energised,
every two memory address. This keeps synchronisation.
The transistor NOT gate also has problems switching cleanly. This lead to problem with the first row
being ghosted to row 16, as the transistor has not switched. But since they ghosting is slight, and replacing it is
not trivial the transistor NOT gate was kept. A simple was to reduce this problem was to make sure that most
text and graphics displayed start at row 2, thereby stopping the ghosting and using row 1 to a minimum.
28 Memory Addressed Display
29 Memory Addressed Display
DISPLAY
LEDS
In the above diagram we can the basic diagram for the display. In each individual display there are 5 *
7 = 35 dots with all the anodes connected and all the cathodes connected. These can be tiled to form a larger
matrix. Here 24 displays, six on the x-axis and 4 on the y-axis, are stacked giving a 30 x 28 display.
The displays have an equal border of 0.1’’ all the way round and hence can be easily tiled with no dis-
tortion. The aspect ratio of the display is 30:28 which equals 15:14, slightly widescreen.
Using 17.3 mm (height) matrices allows the display to have a very high pixel density and also a high
resolution. The display is 3.1’’ by 2.9’’ (~77.3mm x 71.3mm). The LEDs are High Intensity Red, and have a lu-
minance of about 20mC, bright enough for a display, especially when there are 860 of them.
30 Memory Addressed Display
31 Memory Addressed Display
32 Memory Addressed Display
The above diagram shows how the LEDs were connected to each other and to the transistors. Each
LED ideally drops about 2V across it and has about 20mA through it. Because of the multiplexing system there
can be a maximum of 16 LEDs on at any time. Therefore at full capacity, one NPN has to source 16 x 20mA
=320mA, but the PNPs have to sink only 20mA, as each LED has its ‘own’ one. This maximum of 320mA is only
an instantaneous need and is only sustained if every LED is on all 840. The transistors can easily source 1 amp,
so this no problem. Normally a half to a quarter of the LEDs are on in any frame. If the display was not multi-
plexed and all of the LEDs were on then 840 x 20mA = 14.8 Amps is needed which is not practical. Also every
LED would need its own line
Even though the maximum current needed is relatively low sourcing this from the 5V, 1Amp power
supply that feeds the rest of the system would mean overloading the system. Hence the LEDs were supplied
with their own power source from a separate variable power supply. This allowed them not to interfere with
the other circuitry and also adjust the voltage for optimum performance. The power supply was not fed
straight into the emitters of the NPN transistors. It went through a voltage regulator circuit, which first made
sure that the system cannot be over-volted and therefore damaged. It also gives a brightness adjustment, by
means of a 10k potentiometer is connected to the adjust. It de-spikes the voltage in, and smoothes the voltage
out, by using 0.1uF and 220uF capacitors respectively. The smoothing, acts like a power reserve when suddenly
all the LEDs come on and a lot more instantaneously current is needed
The 10K potentiometer is connected to a soft touch knob, which is used to adjust the brightness. The
1K resistor splits the adjust voltage, so that the output can never be too high. A heat sink is used, to cool the
LM317, when it is dropping a high voltage.
I: 16 x 20mA = 320mA
V: 4V - 10V
P = 1.92 W = 3.2W
This includes the power lost as heat in the LM317 voltage regulator and switching the transistors.
A blue power LED is also wired to the output of the LM317, with its brightness proportional to the
voltage out of the regulator.
34 Memory Addressed Display
35 Memory Addressed Display
36 Memory Addressed Display
37 Memory Addressed Display
PCB
ART WORK
The diagrams below show the PCB silk screens used for making the display. This is a two sided PCB, so
green is on the component side (top) and red is on the solder side (bottom). A doubled sided PCB means sol-
dering on both sides, at least where there is a connection. This can be very tricky, especially with the displays.
SILL sockets were soldered in, and then the display was pushed into the socket. This means they can be re-
moved, if needed.
38 Memory Addressed Display
39 Memory Addressed Display
CONSTRUCTION
In the photo below we can see connections from the PCB to the Breadboard. First there is the LSB
and MSB of the Display Bus. Theses go to the row tristates. Then there is the control bus, which has +5V and
GND for the logic on the board. It has Vled for the Display, and also GNDled, a separate ground for the LEDs.
Then there is CLK, which is the Master Display Clock, RES, which resets the column multiplexer, and row
tristates, and finally /EN2, which can disable the display. The last 2 are used by the OUTRAM routine to re-
fresh the display.
40 Memory Addressed Display
41 Memory Addressed Display
SOUND SYSTEM:
A 555 clocks a 7493 binary counter which create a set of frequencies. These are tristated, with control
from output port 3. The tristate outputs are commoned and connected to a piezo buzzer through a potenti-
ometer which acts as a volume control. This arrangement allows various sounds to be heard, through software
control.
42 Memory Addressed Display
ALTERNATE SOLUTIONS
There are a few ways in which this project could have been built otherwise. The display system could
have been build not using LED matrixes but with a LCD matrix. The input system could have been changed, and
the hardware display driver could have been replaced with a software one.
LCD SCREEN
It is possible to buy many LCD screens which could be interfaced with the CPU. This would have
meant a complete different way of driving the display. To achieve similar functionality as the dot-matrix LEDs
i.e. the ability to turn on and off individual pixels would require a matrix LCD screen. These are very expensive,
therefore a cheaper solution would be fixed LCD screen, (16 x 2). Theses work like an ASCII printer, in which a
ASCII code is serially sent to the screen, which using its own decode circuitry turns into text. This means only
text can be shown, and typically because of cost reasons only 2 lines, with 16 characters per line. This is not
satisfactory as with the LEDs we can address single pixels, have graphics, and a much higher resolution. Also
the screen can be built to any dimensions, whereas the LCD is preassembled to an oblong design suited for
text.
The LEDs are also much brighter, and can have a display driver built for its specific purposes. Here to
offload the multiplexing from the Z80 to hardware, giving the CPU more time to work.
Also the LCD typically have a serial interface, which means a method is needed for parallel to serial
conversion from the Z80 ports. This adds complications to the circuitry.
PROS
o Already have drivers built in, therefore the computation of display text is offloaded from the CPU.
CONS
43 Memory Addressed Display
o A similar general memory mapped display, with similar resolution would be very expensive (>£100).
The LEDs were chosen because they can be easily tiled to large sizes, and are relatively easy to multi-
plex and address. This mean anything can be displayed, as the CPU only needs to adjust memory and output.
The LCD, since it is rebuilt with its own driver, would require working around it instead of have the display fit
the CPUs need. The LCD would be smaller, harder to interface, and harder to do arbitrary graphics.
INPUT SYSTEM:
The current input system used control pads which are wired straight into the input ports, as shown on
figure 6. These have terrible bouncing problems, but are corrected in software. The input port polls (repeat-
edly checks the input port) to see if anything has changed.
An alternative to this is to use a switch decoder chip. Up to 16 buttons are wired to this chip on both
pads. This chip automatically de-bounces the switches. It also outputs a 4 bit binary word depending on which
switch is pressed, and it can also trigger an interrupt if any switched is pressed.
Initially it would seen that this chip would be a quick and neat way of interfacing the pads, as it would
de-bounce, allows interfacing 2 pads with only one port, and trigger an interrupt.
The problem is that first, de-bouncing in software is even easier and neater than using a separate
chip. Secondly, as it outputs a binary code depending on which switch is pressed, it is impossible to know if
two switches are pressed at the same time. This is knowledge is lost, but is needed by the software. Triggering
the interrupt for every press is more efficient, but the interrupt is already being used anyway.
PRO
o De-bounce in hardware.
CONS
Event though the chip is novel, its extra complicity and the loss of the ability to see if two or more
44 Memory Addressed Display
switches are pressed at the same time means that the simplest option actually is the best. Wiring the buttons
straight into the input ports, and de-bouncing in software is simple and works.
It is entirely possible to replace the display driver and its video RAM by directly connecting the display
bus to the CPU output ports. This would have reduced the chip count considerably.
This would require the CPU to constantly multiplex the display, thereby outputting the data, and cre-
ating the Master display clock. The problems occur as this puts a huge amount of effort on the Z80. 90% of its
time would be spent multiplexing, therefore a clock increase would be needed. But also multiplexing has to be
regular, i.e. the display must be scanned at least 50 times a second, every second. The rate must be exactly the
same, or the brightness of the display will vary. Also if the display tries to do something else, like creating the
contents, then in that time the screen will not be updated. This is not satisfactory, as the screen will temporal-
ity flicker, or even go blank.
PROS
CONS
o Flicker, and variable brightness, as multiplexing speed changes depending on CPU workload.
o Software must be very carefully written, as it might stall the multiplexing, (eg time wasting routines would
give a blank screen).
The hardware system was chosen, as it puts the repetitive, but non-trivial task of multiplexing the
display out of the way of the CPU. Once it is built, the programmer can forget how it works, as it will always
display the frame. The software solution would require significant consideration during programming, and
would reduce the total throughput of the Z80.
45 Memory Addressed Display
SOFTWARE
SUMMARY
A major part of the system is the software. The hardware is designed to be general; it allows turning
on and off individual pixels dynamically. This means the software is under total control of each of the 860 LEDs.
Thinking about individual dots is no way to write a program as it’s too cumbersome - the display
needs to be abstracted by software. This is done by memory mapping the LEDs to the graphics memory.
MEMORY
The Z80 is configured with a 2K ROM and a 2K RAM. ROM is from address 0000H to 07FFH, while
RAM is from 0800H to 0FFFH. A stack is initialised at address 0FFFH and works its way down. Maskable inter-
rupts are enabled, and the interrupt service routine starts at 0038H. Reusable helper routines are stored from
address 0400H, all the way to the end of ROM. 0 to 0037H, contains the initialisation code. Programs are from
0044H to 03FF. The diagram below shows a memory map of the system.
Basics:
The display driver has its own 16-bit wide RAM which has a bit corresponding to every LED. This is the
frame buffer and contains the currently displayed frame. To change what is being shown, the RAM needs to be
written to. This is done via the system OUTRAM routine and not directly from user code. Normal software ed-
its bits in the internal frame buffer, which is then refreshed to the external RAM. The OUTRAM routine is very
important, as its job is to update the external RAMs with the internal representation.
As user software does not interface with the display driver RAM, it needs to Blit (draw) to aa internal
buffer starting at address 0800H and ending at 0870H. This is 70H address or 112 bytes (4 bytes per row * 28
rows). As one byte has 8 bits therefore 4 * 8 = 32 possible bits per row. This correspond the LEDs but since
there are only 30 LEDs the last 2 bits are not connected on the row tristates. This area of memory is the inter-
46 Memory Addressed Display
nal frame buffer and contains a bit by bit representation of the LEDs. This is how the display is abstracted to
the software. The software doesn’t need to know about the implementation of the display, only this RAM.
When the display RAM is refreshed from this internal frame buffer (by calling OUTRAM) the display will
change. This is the basis of how anything is drawn.
To simple make the first 8 LEDs come on requires the following steps.
3. Call OUTRAM.
This pseudo program shows the basic steps in displaying pixels. When the Z80 is first turned on the
VIDRAM cannot be assumed to be clear, hence it needs to be zeroed. FFH is 11111111B, this is written to the
first byte. The one mean the corresponding LED dot will turn on while a zero is the opposite. Therefore writing
FFH to 0800H will turn on the first 8 LEDs.
OUTRAM needs to be called to refresh the external RAMs with the internal representation. Now the first 8
LEDs are turned on.
Writing 01H (00000001B) to address 0800H + 4 (0804H) would result in the 8th LED on the second
row being turned on. Writing the same 01H to address 0805H would result in the 16th LED on the second row
being turned on. The table below shows how the memory maps to the display.
Vidram 0 1 2 3
0800H |7 ...... 0| |7 ...... 0| |7 ...... 0| |7 .......0|
0804H |7 ...... 0| |7 ...... 0| |7 ...... 0| |7 ...... 0|
0808H |7 ...... 0| |7 ...... 0| |7 ...... 0| |7 ...... 0|
080CH |7 ...... 0| |7 ...... 0| |7 ...... 0| |7 ...... 0|
0810H |7 ...... 0| |7 ...... 0| |7 ...... 0| |7 ...... 0|
0814H |7 ...... 0| |7 ...... 0| |7 ...... 0| |7 ...... 0|
… to 0870J
Each “|7 ...... 0|” refers to one byte of memory and 4 bytes represent one row on the display. This
line of RAM is what the software blits to, and it must work out which bit and byte refer to which LED on the
display. The last 3 bits on column 2 do not represent any LEDs (32 bits cf 30 dots) so can be ignored.
MORE ABSTRACTIONS
It can be seen that writing different combinations to different address in VIDRAM, and calling
OUTRAM mean any possible combination can be displayed. However writing specific bytes to memory loca-
tions is not an easy way to program. It is fine if a static frame needs to be created, but any animation requires
rewriting to VIDRAM. This means the program has to work out the exact bytes for every frame, put them in a
lookup table and copy to VIDRAM. This is very inefficient and time consuming, as each frame would require
112 bytes. Also the dynamic features of having a general purpose CPU are not being utilised. To make life eas-
ier for the programmer, more abstractions are needed.
The Z80 needs to be programmed to automatically create frames from simple instructions. For exam-
ple, the programmer should simple say, ‘I want the string “HELLO” to be placed at co-ordinates (0,4) and the
system should takes care of the rest. To create such a simple programmer API very complex helper
47 Memory Addressed Display
First we need to make more abstractions. Addressing the display as a memory range is very general
and versatile from the Z80s point of view but not user friendly for the programmer. To abstract further, the
display is refereed as a grid with a coordinate system. The origin is to the top left and the first pixel is (0, 0).
The units are discrete and 0 based. On the x-axis we have 0 - 27, representing the 28 columns, and on the
y-axis 0 - 29, representing the 30 rows. Negative co-ordinates are allowed coded using two-complement. The
diagram below shows this setup.
This is much more user friendly for the programmer, as they display can be referred to in a more
natural way. The way this is implemented is by the FIND_PIXEL routine. To use it, register B and C are loaded
with the desired X and Y co-ordinates. When the routine returns it has HL pointing to the right byte in VIDRAM
and the Accumulator has a bit mask which corresponds to the individual LED.
LD B,0
LD C,0
CALL FIND_PIXEL
-----------------------
48 Memory Addressed Display
A = 10000000B
HL = 0800H
Ie the very first pixel: HL points to the byte in VIDRAM, and A has a mask, with 7 zeros and 1 one, the location
of the 1 depends on where the pixel is.
then A= 01000000b
and HL = 08009h
Since there are 4 bytes per row, we multiply the Y value by 4. So if Y = 0, then we could possibly have the first 4
bytes, 0800H - 08003H; if Y=1, then the possibilities are 08004H-08007H. The division tells us if it is the first,
second, third or fourth byte. If X is between 0-7, Int(X DIV 8) evaluates to 0, if X is between 8 and 15 it evalu-
ates to 1 and so on.
A = X AND 00000111
The masking gives a number between 0 and 7, corresponding to the appropriate bit. This is used to select
bytes from the below lookup table.
2. A= mask, HL = byte
3. Execute : A= A OR (HL)
We used the mask and ORed it onto the video memory pointed by HL. Since the mask is the bit
needed, the appropriate bit is turned on. Calling OUTRAM would refresh the display.
2. A= mask, HL = byte
This works by ANDing whatever is at HL, with the complement of the mask. So a mask of 00010000,
evaluates to 11101111 which when ANDed will reset that appropriate bit.
These functions are packaged into the routines PutPixel and Remove Pixel. Other pixel routines are
similarly coded. A summary is provided later, and the full assembler source is in the appendix.
PIXELS TO PICTURES
Plotting pixels at arbitrary co-ordinates is very nice, but this is still inefficient to draw pictures as you
would need to draw it dot by dot. Therefore we must use another abstraction - sprites. A sprite is the equiva-
lent of a bitmap image, ie a bit by bit representation stored in ROM. For example the following assembler:
; Character 0x44 D
DB 8D ; Height of Sprite
DB 11111000B ; Hex F8h
DB 11001100B ; Hex CCH
DB 11000110B ; Hex C6h
DB 11000110B ; Hex C6h
DB 11000110B ; Hex C6h
DB 11001100B ; Hex CCh
DB 11111000B ; Hex F8h
DB 00000000B ; Hex 00h
This is an 8 x 8 sprite for the letter D where ones represent an LED on, and a zero represents off. It looks like
the figure below, when drawn to the screen.
50 Memory Addressed Display
Sprite gives us a nice way of storing and working with frequently used images. The sprite drawing rou-
tine SDR8, blits a sprite, 98-bits wide, arbitrary length to a (X, Y) coordinate. So we can say draw this particular
sprite to co-ordinate (2, 7) and SDR8, using FIND_PIXEL, works out where in VIDRAM to write to.
LD B,10
LD C,12
LD HL,SPRITE <---(Pointer to sprite)
CALL SDR8
CALL OUTRAM
SPRITE: <--- Label
DB 8D ; Height of Sprite
DB 11111000B ;Data
DB 11001100B
DB 11000110B
DB 11000110B
DB 11000110B
DB 11001100B
DB 11111000B
DB 00000000B
The above code will draw the ‘D’ to coordinate (10, 12). By incorporating the above into a loop which
decrement B, clears the screen, waits , then repeats, the ‘D’ will be seen scrolling left across the display.
The simplest way in which a sprite routine would work is by copying the first byte to a location in
VIDRAM, then coping the second byte to the location + 4 (the next row), and so on. This is called aligned
drawing, because we have one byte from the sprite fit nicely into 1 byte in VIDRAM. This limits to the locations
on the x-axis where the sprite can be drawn. Either it starts at 0, 8, 16, or 24, but the y-axis can have any value.
To achieve non-aligned drawing ie when a byte from the sprite is split between two adjacent video
ram bytes, a modified routine is used. The routine needs to work out how much overlap there is and rotate the
byte accordingly. It must then blit the sprite, without destroying anything that was already there. SDR8 can do
all of this.
There is also another complication is that part of the sprite can be off-screen. There are 3 possible
situations. Considering any edge, either the sprite is fully on screen, fully off screen, or partly on and partly off.
As there are 4 edges there are 3*4 =7 possible scenarios. This routine must check for all of them and act ac-
cordingly. If it is fully on screen, then carry on as normal, if it is off screen, then don’t draw, and if it is partly on
and off, then clip. Clipping refers to the process of disregarding the right bits. The clipping version of SDR8 is
SDR8_CL
The way SDR8 works is very complex, so complex that in fact that the version used in this project is a
significantly modified version from a whole set of routines for memory mapped displays written by “JL and
Joa”. It was originally written for a 128x64 screen, so has to be significantly changed. Clipping had to be re-
written, as so did the checks. The full edited source is in the appendix.
Timing of the OUTRAM routine is critical to smooth transitions. If OUTRAM was called every time
VIDRAM was edited there would be screen flicker because of the way routines blit. Individual parts of each
51 Memory Addressed Display
large drawing operation would be seen. By timing OUTRAM right, when all the drawing operation for a par-
ticular scene are finished this flickering is avoided. This is technically called “double buffering” and it is process
of drawing all the little bits that make up a scene to a back buffer and then outputting it all in one go. Manual
control of the OUTRAM routine allows us to implement double buffering.
OTHER ROUTINES
There are many other routines available to the programmer to make their life easier and are summa-
rised below. Most of them call other routines thereby allowing significant code reuse.
Put_Num does its job by calling many other routines. First it takes the binary number and by calling
BINTOBCD converts it into a string of binary coded decimals, which are then converted into an ASCII string,
deleting pre-leading zeros. This ASCII string is created in RAM. Put_Num then calls Put_Small which puts an
ASCII string at coordinates B, C. Put_Small takes the ASCII code, works out where in ROM the letter is stored,
and calls SDR8_CL. SDR8_CL calls Find_Pixel, working out where in the display it is, and draws it non-aligned
with clipping. All this occurs in a few microseconds.
The interrupt service routine is executed every time the interrupt pin goes low, about 100 times a
second. The interrupt routine first checks if the ‘pause’ button has been pressed, if it has then it saves the
screen and displays pause and counts upwards. When another button is pressed it returns. This gives a pause
function which allows freezing in the middle of the main routine.
The interrupt service routine also does the housekeeping of the sound system, making sure it is reset
and the right sound is playing
SOFTWARE SUMMARY
Routine Address
OUTRAM 400H
Find_Pixel 441H
Sdr8_Cl 048AH
Put_Pixel 046AH
Remove_Pixel 0472H
Change_Pixel 047BH
Test_Pixel 0483H
Clear_Vram 051CH
Put_Char 0529H
Put_Small 0565H
Rand 0634H
Binbcd 0646H
Put_Num 069CH
Wait 06B2H
Pause 06BcH
Sound 0726H
52 Memory Addressed Display
RAM ADDRESS’
Address Routine
0800 - 0870 Video Buffer
0880 -08F0 Pause_Temp
0900 Keyram1
0901 Keyram2
0902 Clipflag
0903 Sound_0
0904 Sound_1
0905 Sound_2
0950 Puttext Temp Ram
0960 Randseed
0961 Bcd16
0966 Bcd16String
Name: FindPixel
Function: Abstracts coordinates to memory
Input: BC = (X,Y)
Returns: HL= pointer to VIDRAM, A=MASK
Name: OUTRAM
Function: Refreshes external frame buffer with internal buffer
Input: None
Returns: None
Name: SDR8_CL
Function: Draws a 8 x n sprite to arbitrary coordinates
Input: BC=(X, Y), HL= pointer to spite
53 Memory Addressed Display
Returns: None
Name: Put_Char
Function: Puts the a ASCII character at arbitrary coordinates
Input: BC = (X, Y), D = ASCII character
Returns: None
Name: Put_Small
Function: Puts a ASCII string limited by a 0 at arbitrary coordi-
nates
Input: BC = (X, Y), HL = pointer to string
Returns: None
Name: Put_Num
Function: Puts a 16-bit binary number at arbitrary coordinates
Input: DE = 16-bit number, BC = (X, Y)
Returns: None
Name: Random
Function: Returns a pseudo random number
Input: None
Returns: A = number
Name: Wait
Function: Wastes cycles for a chosen time
Input: C = multiplier
Returns: None, It returns after a wait
There entire source code can be found in the appendix. The above helper functions allow writing very
complex code. This project uses them to prove a menu interface with selectable choices for programs. The
program Scroller is also coded to allow user selected text to be scrolled across the screen.
54 Memory Addressed Display
DIARY
The Z80 system was built subsystem by subsystem and separately tested. The clock was tested with a
frequency counter and an oscilloscope. The address and IO decoders were tested by entering a manual binary
code, and seeing with the logic probe that the right output was going low. The address and data buses were
testing using continuity meters as was every wire. A reset button was built for the Z80, and a RC network was
connected to it, to auto reset on power up
The ports were tested by writing a simple program, like output FF to port 1. This is where the prob-
lems started. The output and input ports would not function correctly. A small program which copied the input
to the output, only worked when a low was put in. When a high was put in, the output ports pulsed propor-
tionally to clock speed. After checking every wire and, replacing the Z80, the problem was found to be that the
input for the IO decode was going into /RD instead on /WR. This meant the output ports were being triggered
every time the input port was being triggered.
After that, all output ports and input ports were tested using the copycat code, with a LED segment
wired up - They all worked.
Once the Z80 was known to work the clock for it was replaced with a crystal oscillator. This was built,
but it would not clock the Z80. After looking at it with an oscilloscope, the waveform was found not to be
clean. A Schmitt trigger was wired to clean it up.
WEEK 2,3
The display driver was quite easy to construct and test. The resetting of the 4024 was checked by an
LED array, and a slow MDC. The MDC was adjusted with 2 potentiometers, so that the ghosting was minimal.
The shape of the MDC was adjusted, but the original was found to give best performance.
The RAMs were tested by writing known data into them, and seeing if they existed. The control bus was
checked by a continuity meter, and writing a test program to put the system into different modes, and check-
ing with a logic probe.
Before the PCB was designed, the individual sub-circuits were testing on a spare bread-board. The
LM317 voltage regulator was tested this way, this allowed a trial and improvement to find a good resister
value to split the voltage. When the LED matrix arrived, it was found that they were wired the wrong way
around from their literature. This was not a problem, as the analogue switch has a W input that can be any
voltage. This was changed from 0V to 5V, the transistors were swapped, and inverting tristates were used.
The transistors were wired up to 1 display on a breadboard, but there was a large brightness problem.
This seemed to occur only when the LEDs where pulsed. The loss in brightness was way more than it should
have been. After testing with a volt meter, it was found the PNP transistors were dropping twice the voltage
needed. This was evidence to find out that the PNP transistors were in fact Darlington pairs therefore twice
the forward bias was being dropped (1.4V instead of 0.4V). Replacing these with non-Darlington’s solved the
55 Memory Addressed Display
problem. A base resistor value of 3R9 was selected, as this gave enough protection without sacrificing bright-
ness.
The PCB was designed using PCB Wizard software. It was a double sided beast that took over 20 hours
to design. Once the PCB was designed, it was printed to transparencies. The first side was exposed to UV, de-
veloped, and etched. The first side was then protected with gaffer tape, while the second side was exposed,
developed, and etched. Both sides lined up perfectly. All this was done by the multitalented Mr Evans.
Once the PCB was created, it needed to be drilled. This took quite a while, needing two drill bits as
they were worn down. Repair work was needed on the tracks that did not etch properly as well as some that
were touching. This was pretty trivial. The components were then soldered in, including 58 resistors and 58
transistors. Since each transistor has 3 legs and need to be soldered on both sides, this is tiresome. Add in all
the chips, also double sided, it can be seen why the PCB construction took so long. The SILL sockets were then
soldered in, on both sides, and then the displays were put in. They were tested by pulling lines high and low,
and seeing if the right LED came on. Some did not, and the problem was found to be dry joints which were
fixed. Throughout construction pin to pin connections were checked by a continuity meter.
Once the entire PCB was finished, three connectors were needed to connect the PCB to the bread-
board. The display was tested by using a test OUTRAM program with a pre-known frame. This showed that the
connectors were the wrong way round. Test programs were also written to see if the refreshes were correct.
The sound system was built and tested by playing different sounds. The speed of its clock was ad-
justed to make the most interesting noises. Software was written to test the sounds.
The pads were constructed on PCBs, and tested with logic probes. The subtle bouncing problems
were discovered later when there was working code. This led to the development of a software denouncing
solution.
The interrupt clock was first an equal mark space, by this made the interrupt trigger way too often. It
was then shaped using a reset signal of a clocked 4017, which worked better.
56 Memory Addressed Display
RESOURCES
Component Price
Double sided PCB £15
25 displays £35
Chips £5
Sill sockets/connecters £3
Other £10
Switches £2
Total £70
57 Memory Addressed Display
EVALUATION
In general the project fitted the specification on all accounts. The display was a general memory
mapped one. When the system is reset an animation is shown, then a menu. The user can select from 3 pro-
grams, one resets the system, the other is a ‘Scroller’ program which allows the user to input a string which is
then scrolled across the display, from left to right, at random y values. There is also a sound test program with
plays different sounds when different buttons are pressed.
o The project is built on a breadboard and PCB using the allowed components and equipment.
o The project was completed within 3 weeks, and in the feasibility of the equipment requirements.
o The required sound test and Scroller programs are coded, and work.
o A Z80 microprocessor system clocked at 4MHz, with 4 output ports and 2 input ports was created.
o The MDC was adjusted to give best performance (minimal ghosting, max brightness).
o The Display was built as specified, with a total of 840 dots driven through transistors.
o The column multiplexer and row tristates work as they should, after repair work.
The system has some minor problems but they were fixed, therefore the entire system fitted the specification
on all accounts.
58 Memory Addressed Display
ACKNOWLEDGEMENTS
GENERAL
Mr Evans, for help on soldering, PCB design, PCB construction, connector construction, transistor se-
lection etc. Mr Marvin, on Z80 construction and trouble shooting.
BOOKS
INTERNET
The Giant IC Masturbator: Great site having data on virtual every chip ever made.
www.ti86.acz.org: How to program a Z80 based graphics calculator, which was the inspiration for this project.
OTHER
Ti86 Graphics Calculator, Texas Instruments: Even though I do not own one, this project would not exist if it
were not for this calculator. It is based on a Z80, has a memory mapped LCD display and a lot of code is avail-
able for it.
SOFTWARE
APPENDIX
HARDWARE
4067
74240
Dual 4-bit 3-state inverting buffer/line driver.
+---+--+---+
/1OE |1 +--+ 20| VCC
1A1 |2 19| /2OE
/2Y4 |3 18| /1Y1
1A2 |4 17| 2A4
/2Y3 |5 74 16| /1Y2
1A3 |6 240 15| 2A3
/2Y2 |7 14| /1Y3
1A4 |8 13| 2A2
/2Y1 |9 12| /1Y4
GND |10 11| 2A1
+----------+
74244
Dual 4-bit 3-state noninverting buffer/line driver.
+---+--+---+
/1OE |1 +--+ 20| VCC
1A1 |2 19| /2OE
2Y4 |3 18| 1Y1
1A2 |4 17| 2A4
2Y3 |5 74 16| 1Y2
1A3 |6 244 15| 2A3
2Y2 |7 14| 1Y3
1A4 |8 13| 2A2
2Y1 |9 12| 1Y4
GND |10 11| 2A1
+----------+
60 Memory Addressed Display
EI ;RE-ANABLE INTERUPTS
;Routine to update external ram with interal vram buffer RET
;© Dharmesh Malam 2002
END
;PIN 0 = Trisate port 1 and 2, when high, ports are high impeadance, i.e. active low
;PIN 1 = Main Display Clock enable, active high, hgh for normal operation -------------------------------------------------------
;PIN 2 = Reset column/row select logic, active high ORG 000H
;PIN 3 = Reset ram counter, active high START:
;PIN 4 = /rd ,active low
;PIN 5 = /wr ,active low LD SP,0FFFH ;INITIALISE STACK
;PIN 6 =Manual clock of ram IM 1
;PIN 7 =/en2, low for normal operation XOR A
LD (0903H),A
;NORMAL MODE LD (0904H),A
;76543210 LD (0905H),A
;00100011 INC A
LD (0960H),A
;ROUTINE STOPS MDC EI
;THEN RESETS COLUMN,ROW LOGIC, disables screen CALL CLEAR_VRAM
;THEN RESET RAM COUNTER JP LOGO
;MAKES /RD HIGH
;LOAD DATA ON PORTS 1 AND 2
;ENABLES PORT TRISTATES --------------------------------------------------------
;PULSE /WR ORG CLEAR_VRAM
;PULSE CLOCK
;REPEAT UNTIL ALL RAM IS UPDATED CLEAR_VRAM:
;DISABLE PORT TRISTATES PUSH HL
;RESET LOGIC, AND RAM COUNTER XOR A ;ZERO A
;MAKE /RW LOW LD HL,VIDRAM
;START MDC LD B,112 ;ROWS/8 * COLUMNS
;RETURN CLEAR:
LD (HL),A
#include zinc.asm INC HL
DJNZ CLEAR ;CLEAR VIDRAM
ORG OUTRAM POP HL
RET
OUTRAM:
DI ;DISABLES INTERUPS, FOR SPEED ;IF SOUND_X IS ZERO, TURN OFF SOUND
EX AF,AF' ;IF SOUND_X IS NON-ZERO, THEN TURN ON SOUND FOR THAT MANY 100THS SEC
EXX ;
; 00100011
LD A,10110001B ;MAKE /RD HIGH, AND STOP MDC, /en2 -> high SOUND_0 EQU 0903H
OUT (2),A ;OUTPUT SOUND_1 EQU 0904H
SOUND_2 EQU 0905H
LD A,10111101B ;MAKE RESET ON COL/ROW LOGIC AND RAM COUNTER
HIGH snd:
OUT (2),A ;OUTPUT PUSH BC
LD B,0
LD A,10110100B ;KEEPS COL/ROW LOGIC HIGH, AND MAKES RAM
COUNTER LOW, AND ENABLES TRISTATES SND_0:
OUT (2),A ;OUTPUT LD A,(SOUND_0) ;GET SOUND VAR
CP 0 ;IS IT ZERO
LD HL,VIDRAM ;POINT TO VIDRAM JR Z,SND_1 ;IF SO END SOUND
61 Memory Addressed Display
add hl,de ;and add offset to get where to put sprite LD E,(HL) ;E=NUMBER OF ROWS IN SPRITE
INC HL ;NEXT BYTE (POINTS TO SPRITE NOW)
add a,a ;-> sets all bits to the right of set bit (for mask) XOR A ;ZERO A
dec a ;/ LD (CLIPFLAG),A ;CLEAR CLIPFLAG
ld e,a ;save mask into e
ld a,b ;a=x coor ; TOP CLIPPING DONE
and %00000111 ;find remainder of x/8
inc a ;get range between 1-8 CHECK_RIGHT:
ld b,a ;and save rotate counter LD A,B ;A=X COOR
BIT 7,B ;IS X NEGATIVE?
SDR8_NewRow: JR NZ,SDR8CL_CHECKLCLIP;IF SO THEN JUMP TO CHECK LEFT
ex (sp),hl ;hl(video location)<->(sp)(pointer to sprite) CP 30 ;CHECK IF X IS GREATER THAN OR EQUAL
ld a,(hl) ;a=byte in sprite TO 30
inc hl ;next byte JR NC,ENDSDR ;IF SO, THEN CARRY IS SET, AND JUMP
ex (sp),hl ;hl<->(sp) JR CHECK_BOT ;ELSE, DONE L/R CLIPPING (RIGHT
push bc ;save rotate counter and row counter CLIPPING IS "AUTOMATIC")
ld bc,$10-1 ;bc=number of bytes in one row subtract one LD A,28 ;ROWS IN DISPLAY
add hl,bc ;add to point hl to next row SUB C ;SUBTRACT THE Y-COORD
pop bc ;restore rotate counter and row counter LD E,A ;USE ABOVE RESULT AS REDUCED ROW
dec c ;decrease row counter COUNTER
jr nz,SDR8_NewRow ;and repeat until whole sprite is drawn ;BOTTOM CLIPPING DONE
pop hl ;restore hl (which now points to next byte after sprite)
ret ;return JR SDR8CL_DONECLIP
----------------------------------------------------------------- CHECK_TOP:
PAUSE_TEXT: DB 00000100B
DB "PAUSE",0 DB 11100100B
DB 00000000B
---------------------------------------------
;© Dharmesh Malam 2003 ; Character 0x2C ,
DB 11101010B
DB 01000000B ; Character 0x40 @
DB 00000000B
DB 01001010B DB 00000000B
DB 10101010B
DB 01000000B ; Character 0x5F (underscore)
DB 10101010B
DB 01000100B INVERT_CUR
DB 01000000B PUSH BC
LD HL,VIDRAM
; Character 0x5A Z LD B,0
SLA C
DB 11100010B SLA C
DB 01001000B ADD HL,BC
DB 11100000B LD B,4*6
MENUDOWN: LD B,32
IN A,(0) LD HL,TEMP_STRING
BIT 6,A ZERO_TEMPS:
JR Z,MENUL XOR A
LD (HL),A
CALL INVERT_CUR ; SAME AS UP, GO BACK INC HL
TO NORMAL TEXT DJNZ ZERO_TEMPS
LD A,C ; GET LD E,A
CURRENT ENTRY FOR CHECK
CP 20 ; AT THE FROM_DISP:
BOTTOM? CALL CLEAR_VRAM
JR Z,MENUDOWNT ; THEN MOVE TO THE
TOP LD BC,0000 ;RESET COORDS
ADD A,6D ; NEXT LINE LD HL,ENTER1 ;POINT TO 'ENTER' TEXT
LD C,A ; SAVE CALL PUT_SMALL ;DRAW TEXT
JR MENUBAR ; HANDLE MENU BAR LD BC,7 ;INC Y COORD
LD HL,ENTER2 ;POINT TO 'TEXT'
MENUDOWNT: CALL PUT_SMALL ;DRAW
LD C,8D ; MOVE TO THE TOP
LD D,32 ;LOAD THAT CHARACTER
MENUBAR: INTO D
CALL INVERT_CUR ; INVERT THE NEW NORMAL:
SELECTION LD B,22 ;PUT CHAR IN BOT RIGHT
CALL OUTRAM LD C,22
PUSH BC LD HL,TEMP_STRING
LD C,00AAH CALL PUT_SMALL
CALL WAIT CALL OUTRAM
POP BC
JR MENUL ; NOW IT'S TIME TO LOOP
INPUT_WAIT: ;LOOP TO EDIT TEXT
PUSH BC
MENUSELECT: LD C,00FFH
CALL WAIT
PUSH BC POP BC
LD C,00AAH
CALL WAIT INPUT_WAT
POP BC IN A,(0)
JM_1: DOWN:
DB 0 LD A,31
DB 0 DEC D
JM_2: CP D
DB 0 JR NZ, HERE1
DB 0 LD D,95
JM_3: JR HERE1
DB 0
DB 0 ENTER:
LD A,32 ;MAX NUMBER OF CHARS
---------------------------------------------------------------- CP E
;© Dharmesh Malam 2003 JR Z,INPUT_WAIT ;JUMP IF AT THIS NUM
;Scrolls user inputted text across the screen
;at random y values LD (HL),D ;SAVE CHARACTER
;© Dharmesh Malam 2002 INC E
69 Memory Addressed Display
LD A,B END
SUB 4
LD B,A -----------------------------------------------------------------
PUSH DE LD B,0
LD D," " LD C,20
CALL PUT_CHAR ;CLEAR BIT ON LEFT INC HL ;PRESENTS
CALL PUT_SMALL
LD A,B CALL OUTRAM
ADD A,4 LD C,00FFH
LD B,A LD B,4
PUSH BC ;SAVE X,Y WAIT_L:
LD HL,TEMP_STRING CALL WAIT
CALL PUT_SMALL DJNZ WAIT_L
POP BC
POP DE CALL CLEAR_VRAM
CALL OUTRAM LD B,0
JR INPUT_WAIT LD C,4
INC HL
DISP: ;WE HAVE A STRING TO CALL PUT_SMALL ;MEMORY
DISPLAY
CALL CLEAR_VRAM LD B,0
LD C,0 ;Y, IE TOP LINE LD C,10
INC HL
LOOP_INIT: CALL PUT_SMALL ;ADRESED
LD D,E ;NUMBER OF CHARS
LD A,30 ;ONE DISPLAY LD B,0
SLA D ;X2 LD C,19
SLA D ;X4 INC HL
ADD A,D ;ADD TOGETHER CALL PUT_SMALL ;DISPLAY
LD D,A ;THIS IS THE COUNTER CALL OUTRAM
LD C,00FFH
LD B,30 ;X, JUST OFF SCREEN LD B,4
WAIT_LL:
DISP_LOOP: CALL WAIT
LD HL,TEMP_STRING ;POINTER TO STRING DJNZ WAIT_LL
PUSH BC
PUSH DE
CALL PUT_SMALL ;DRAW WITH CLIPPING LD HL,VIDRAM
AT BC LD B,112
POP DE INVERT:
LD A,(HL)
CALL OUTRAM ;OUTPUT CPL
CALL CLEAR_VRAM ;CLEAR INTERNAL VRAM LD (HL),A
CALL OUTRAM
LD C,00AAH INC HL
CALL WAIT ;WAIT 1 TENTH LD C,10
POP BC CALL WAIT
DJNZ INVERT
IN A,(0)
BIT 1,A
JR NZ,FROM_DISP CALL CLEAR_VRAM
BIT 2,A LD D,18
JR NZ,MENU
LD B,0
DEC B LD C,0
DEC D LD HL,MAD
JR NZ,DISP_LOOP ;LOOP 30+4(NUM_CHAR) SLIDE:
CALL PUT_SMALL
LD A,R CALL OUTRAM
AND 00011111B PUSH BC
SUB 2 ;GET RANDOM NUMBER LD C,0AAH
BETWEEN -2 AND 30 CALL WAIT
LD C,A POP BC
JR LOOP_INIT ;LOOP INC B
INC C
DEC D
ENTER1: DB,"ENTER",0 JR NZ,SLIDE
ENTER2: DB,"TEXT:",0
LD B,3
ORG 096AH LD C,19
TEMP_STRING: DB,0,0,0,0,0,0,0,0 LD HL,FACE
DB,0,0,0,0,0,0,0,0 CALL SDR8_CL
DB,0,0,0,0,0,0,0,0,0 CALL OUTRAM
70 Memory Addressed Display
LD C,00FFH
LD B,2
WAIT_LLL:
CALL WAIT
DJNZ WAIT_LLL
LD B,112
SHIFT:
PUSH BC
LD HL,0870H-4
LD DE,0870H
LD BC,112
LDDR
CALL OUTRAM
LD C,90H
CALL WAIT
POP BC
DJNZ SHIFT ;SHIFT DOWN THE DIPLAY
LD C,00FFH
CALL WAIT
JP 0044H
TEXT1:
DB "DARMESH",0
DB "MALAM",0
DB "PRESENTS",0
DB "MEMORY",0
DB "ADRESED",0
DB "DISPLAY",0
MAD:
DB "MAD",0
FACE:
DB 8
DB 00111100B
DB 01000010B
DB 10100101B
DB 10000001B
DB 10100101B
DB 10011001B
DB 01000010B
DB 00111100B