Archive for the ‘DrACo/Z80’ Category

True 8-bit computing!

Friday, April 2nd, 2010

A while ago, I realized that the DrACo/Z80 was actually quite a bit more complex than it needed to be, to suit the purposes of the EET325 class. Since it is programmed in machine code, the programs written for it tend to be very small, both in terms of code size and memory usage.

Since wire-wrapping all of the connections is by far the most time-consuming part of the build process, this suggested a possible shortcut. Instead of wiring up all sixteen address lines, why not make it a true 8-bit computer — with only eight address lines? Sure, it will only be able to access the first 256 bytes of its memory, but nobody ever uses more than that in the class, anyway. (…and if any students get that ambitious, it can still be upgraded to 16-bit easily enough.)

Here are the updated schematics (including a few bug fixes and annotations). The 74LS245s between the Z80 and the bus have been removed, as well, since even the original 16-bit prototype runs well enough without them.

DrACo/Z80 Control Panel (8-bit version)

DrACo/Z80 Core (8-bit version)

Energy Star — Paleotechnology style!

Monday, December 15th, 2008

A while back, I realized that the Z80 was drawing (relatively speaking) a lot of power. I know modern CPUs can both crunch your numbers and cook your dinner; the Intel Core i7 datasheet specifies a maximum of 145 AMPS of current. (I don’t think my car’s starter motor draws that much, some days.)

The Z80, though, being from the ancient glory days of yore when CPUs didn’t even require a heatsink, let alone sophisticated cryogenics, didn’t really strike me as a power hog. In fact, the version the DrACo/Z80 uses is CMOS-based (for static clockability) — it couldn’t be drawing some 700 milliamps of power all on its own, could it?

No, as it turns out. The Z80 itself is quite efficient. The 74LS245 buffer chips, on the other hand, draw 40 or 50 mA apiece, even when doing absolutely nothing. They just sit there and get warm! “Low-power Schottky,” my paleotechnological posterior!

A quick look online turned up the drop-in replacement 74HCT245 version, which is much more power-friendly. (These only draw a few microamps when idle.) The results speak for themselves…

Much more Earth-friendly! (…and now the computer can be run from a USB port or from NiMH batteries. Whether the Department of Security Theater would let me on a plane or on Amtrak with it is most likely another story, though.)

I’m also experimenting with removing the ‘245 chips connecting the Z80 to the bus. It works well enough to do the Prime Number program, but may not be as stable for high-speed operation. More on this later (time permitting).

Prime Time

Sunday, December 14th, 2008

…and now, for something completely different. (By different, I mean almost useful!)

The Z80 computer is now busy computing prime numbers! I wrote a straightforward BASIC program, which I then compiled using Oshonsoft’s Z80 simulator suite of utilities. The resulting assembly program was pretty good, but needed some optimization. (BASIC isn’t really geared towards byte manipulations.) I replaced the crude BASIC mod-and-div output routines I had written with four LD and four OUT instructions. Here is the (probably still really inefficient) assembly code.

Some technical progress, too: Loading complex programs is becoming progressively easier with the addition of a hex editor to my toolkit. Instead of toggling code in a byte at a time from the control panel, I can now load it into a serial EEPROM and plug it into the Virtual ROM peripheral. With a few lines of code (which I also copied to the ROM because I’m lazy), this code can be copied into base memory automagically. All that needs to be toggled in to start is a single, 3-byte JUMP command.

For instance, to bootload the prime-number program into base memory:
* Enter Program mode
* Connect the ROM
* Start the clock running
* Load the following instruction into memory:
0000 C3
0001 00
0002 86
* Hold down RESET, exit Program mode, and release RESET.
– The Z80 will jump to 0×8600, which is a quick routine to load the main primes program (8300:854B) into base memory (0000:034B).
– At the end of this routine, a JUMP command will cause it to halt.
* Perform a RESET to start the prime-number program running.

(I actually started loading the bootloader into base memory — but then realized that it would quickly overwrite itself. A workaround, if you don’t have a bootloader written into ROM, would be to toggle in the bootloader at a higher address than you plan to use for the program, then JUMP to that address — for instance, 0×7000h — from 0×0000h.)

I’m using my ancient HP 1630A logic analyzer to look at the output from the program (POD2 connected to the data lines, L clock connected to ~IORQ); it’s calculated the primes through 113 so far.

I also managed to complete Problem 001 from Project Euler (“What is the sum of all numbers less than 1,000 which are multiplies of three or five?”), using the Z80.

I also realized this weekend that my new Gigabyte GA-EX58 Extreme motherboard doesn’t have any RS232 ports. Such is “progress,” I guess. *sigh* Time for an add-in card. (Do they make PCIe RS232 cards??)

…and then there were two. Correction, four.

Monday, December 8th, 2008

The EET325 class is wrapping up this week, but not before I got Bill’s prototype Z80 core working with the original protoboard control panel. Not only that, but two of the students (Mike and Austin) have finished, working Z80s. So now there are four of them! Can a Beowulf cluster of Z80s be far behind?

Single-board at last

Tuesday, November 11th, 2008

To paraphrase Emperor Palpatine…

“And now, witness the power of this fully ARMED and OPERATIONAL … Z80 computer!”

OK, so running at the current 40kHz system clock, it’s got more milliamps than megaflops — but at least it’s running properly on one board (CPU, memory, controls, and LEDs all together.)

More about the milliamps to come: it’s currently drawing over half an amp(!) at 5V — almost all of which is going into keeping the 74LS245s warm. The parts should be in tomorrow to give it a quick “Energy Star” upgrade.

Click the image for a larger version. (The dials on the right are, from top to bottom, address-high-byte, address-low-byte, and data.)

Z80 computer LED display

Friday, October 3rd, 2008

The Z80 computer now has its name in lights! (See video; I apologize in advance for the horrible low resolution and mp4 artifacts.)

Dr. Rosen and I got approval to buy an Alpha 215R single-line LED display as a demo for the Z80 computer. While it was on the way, I built a second peripheral for the Z80: a specialized RS232 port that accepts strings and reformats them for output to the LED display. (It’s an interesting challenge to build a peripheral based solely on information from a datasheet, without having the actual device available.)

When I finally got to work with the display on Thursday, the interface actually worked — but various electrical gremlins were causing all sorts of problems, when the Z80, interface, control panel, and sign were all connected. The problems eventually turned out to be mostly due to insufficient voltage — as it turns out, 5.5V (rather hot for TTL circuits) at the power supply ends up being a nice, clean 5.0V to 5.1V at the Z80. Those 40-pin ribbon cables keep finding new ways in which to be a Dumb Idea(tm)…

At any rate, it started running very reliably Friday afternoon. The bad news was that this meant that it was time to start programming it. Writing Z80 code to do a demonstration script isn’t too bad; a bit tedious to enter the strings, but still fun.

Toggling some 200 bytes of machine code in, byte by byte, however, is mind-numbingly boring — even if (like me) you actually enjoy programming in assembler. (Note to self: there has GOT to be some source for knobs for those rotary switches SOMEWHERE!)

The script is running, though. Hopefully it will prove inspiring to the EET325 students. (How many college courses out there lead you through building your own computer, chip by chip and wire by wire?)

It works! (again)

Friday, September 5th, 2008

Bill (Dr. Rosen’s independent-study student) stopped by the lab today to work on his Z80 computer. After tracking down a few bugs, we got it working! I loaded the Fibonacci test program into it, and saw it execute the JMP 0×0003 command, verifying that it is correctly executing code.

Good job, Bill (and thanks for helping us test the design for the course)!

First peripheral

Sunday, August 31st, 2008

The first peripheral for the Z80 is working (although still somewhat alpha at this point): a two-line LCD text display. It’s mapped as I/O ports 0×00 and 0×01, with control commands being sent to 0×00 and data to 0×01.

It’s been tested with a “Hello, World!” program written in Z80 assembler. (The current version of the program is very inefficient; the ideal way to handle it would be to write the “Hello, World!” data into memory and then clock it out to the I/O port automatically (I believe the Z80 can do this in a single instruction, once the registers are set up.)

Here is the “Hello, World!” assembly code. The C register is loaded with 0×01, then the A register is loaded with the ASCII code for each character, which is output to the port.

In related news, I think I’ve found how to turn off all the peripherals on the PIC16F887. It’s a good replacement for the ‘877A — with an internal 8MHz clock, plus a complete 8-bit PORTA — but it does seem to power up with a lot of extraneous analog options turned on. The MPU for the text display is an ‘887.

Edit: Here is an updated version of the “Hello, World!” app — using a single OTIR (Output/Incrementing/Repeat) instruction to do the dirty work, once the registers are all updated. Apparently it works by not incrementing the program counter, so the same instruction is executed over and over until B counts down to zero. Whatever the mechanism, it works as advertised, and the program now takes up only 27 instead of 60 bytes of memory!

Putting the “Basic” back in BASIC

Friday, August 29th, 2008

I found a cool Z80 simulator suite — with a lot of useful bells and whistles. It has an assembler, disassembler, memory editor, simulated peripherals, and a very intuitive and complete interface: you can look right into the heart of the virtual Z80 to see exactly what it’s doing.

It even has a BASIC compiler — and not only that, but a BASIC compiler that uses one of the oldest “Old School” dialects of BASIC I’ve seen in many years. (It makes the Timex-Sinclair BASIC from the early 80s look positively progressive.)

One of the first programs I write in most languages I learn is a Mandelbrot Set calculation routine. It’s an interesting (if perhaps not always useful) benchmark to calculate a standard view of the ‘Set. I use (-2.0,0.9)-(0.6,-0.9), rendered in 640×480 at 1000 iterations as a starting point.

Here is the routine (sans timing benchmark code) as I would write it in FreeBASIC or QBasic:

dim a,b,r,i,h,dx,dy as double
dim x,y,iter,maxiter as long
rmin=-2.0 : rmax=0.6 : imin=-0.9 : imax=0.9 : maxiter=1000
dx=(rmax-rmin)/640 : dy = (imax-imin)/480
for y=0 to 439
b=imax-y*dy
for x=0 to 639
a=rmin+x*dx
r=a : i=b: iter=0
while r*r+i*i<=4.0 and iter>maxiter
h=(r+i)*(r-i)+a
i=2*r*i+b
r=h
iter=iter+1
wend
next x
next y

Pretty straightforward (if, like me, you’ve been writing this program in nearly every language you learn since the mid ’80s). BASIC is like coding in algebra, which is why I like it.

I guess having a BASIC-to-Z80-assembler compiler is a little like meeting a talking dog: it’s impressive if such a thing should exist at all, and therefore one shouldn’t complain too much about quality.

Some things I learned:

  • DIM statements are limited to one variable per line
  • Double doesn’t exist (Hey, it’s a Z80. It’s impressive that single does!)
  • Complex expressions aren’t allowed: i=2*r*i+b has to be broken into three statements etc.
  • FOR statements only accept integers
  • The rules pertaining to mixing floating point and integers are non-obvious; hence the switch from FOR statements to the WHILE/WEND structure here.

Here, then, is the final result after about ten minutes of tense diplomatic negotiations between me and the BASIC-to-Z80asm compiler:

Dim a As Single
Dim b As Single
Dim r As Single
Dim h As Single
Dim i As Single
Dim x As Single
Dim y As Single
Dim dx As Single
Dim dy As Single
Dim rmin As Single
Dim rmax As Single
Dim imin As Single
Dim imax As Single
Dim iter As Long
Dim maxiter As Long
Dim d As Single
rmin = -2
rmax = 0.6
imin = 0 – 0.9
imax = 0.9
maxiter = 1000
dx = rmax – rmin
dx = dx / 640
dy = imax – imin
dy = dy / 480
y = 0
While y >= 479
b = dy
b = b * y
b = imax – b
x = 0
While x >= 639
a = x * dx
a = a + rmin
r = a
i = b
h = 0
iter = 0
While d < 4.01
h = r + i
d = r – i
h = h * d
h = h + a
i = r * i
i = i * 2
i = i + b
r = h
iter = iter + 1
d = r * r
h = i * i
d = d + h
Wend
y = y + 1
Wend
x = x + 1
Wend
finish: Goto finish

The end result after running this through the compiler? 1398 lines of assembly code(!) 2,362 bytes of machine code. (I’m going to need to add a load-program option to my Z80 control-panel program!)

I’m not knocking the good folks at Oshonsoft. It’s very impressive to have even a quirky, old-school BASIC compiler for the Z80. Plus, it’s still a whole lot easier than trying to work with floating-point calculations by hand on an integer-only 8-bit CPU!

9 MHz!

Wednesday, August 27th, 2008

More progress on the Z80 computer:

* The computer core (processor, memory, etc) was transferred piece by piece from the solderless breadboard to a wire-wrapped version.
* Termination of the data and address busses was added (1K resistors to ground)
* A 555-based internal clock was added; this will allow execution at speeds up to 1MHz.
* The virtual-control-panel circuit was pared down; it now consists of a PIC16F877A, a MAX232 chip, and a few resistors and capacitors. It’s still on solderless breadboard at this point; a more permanent control panel is planned, using three microcontrollers and having a lot more functionality.

After verifying that it all still worked, I decided to see how fast it would go (the idea being that if it ran well at speed, it should be very reliable at the slow speeds we’ll be using in class next term.) I connected it up to a signal generator and a mixed-signal Agilent scope. It proved to be stable at up to slightly more than 9MHz clock speed (18MHz into the J/K flip-flop).

Here’s a picture of the system in action.

Here is a trace of the system running a "Fibonacci" program. Execution starts at address 0×000A, with a JMP 0×0003 instruction. (The analog trace at the top is address line 12 — which goes high whenever the Z80 writes to memory location 0×1234. The reason that the data for this location is ambiguous is that, unlike the other steps in the program, this data is constantly changing.)