Welcome to my retro computer (single board Z80) playground. My goal is to make the smallest possible single board Z80 computer (cpu, rom, ram, serial I/O) that permits me to experiment with Z80 assembler, some of the Z80 cpu pins like ~wait and ~reset, and to get CP/M running. The latter is rather a feature than a prerequisite.
My design phase has multiple iterative steps. The first step is drawing the circuit schematics of a Z80 single board computer as I think it should be. During the following steps, I eliminate all the hardware features that I estimate unnecessary for this first board, I replace the IC's that are hard to obtain where I live, and the elements that are too complex for a first PCB. After all, I'd like to outsource the creation of the PCB to OSH Park, and even though they charge only $5 per square inch, a PCB order comes in the order of $30-$40 when I shrink everything down as much as possible. Please do take into account that I'm not a professional with tens of years of experience in PCB design.
The first schematic that I've designed is the following. You can click on the image to get a larger version in PDF format. The following characteristics have been foreseen:
The second schematic already limits the functionality and the logic. More specific:
The third schematic seems to be the final version. This version only contains 4 IC's:
The circuit is further reduced by making the following choices:
Since my goal is to go all the way and make a PCB of the third design, extra checking of the circuit is important. Not only the connections have to be ok, but the circuitry and possibilities of the AtMega32 have to be tested. Especially the AtMega32 reset circuit has to be conform to the production specifications of Atmel. On top of that, I like to test if the AtMega32 can generate a block wave of sufficient quality to keep the Z80 going.
An other software question that rises is the possibility to do a hardware reset of the Z80 and a software reset of the AtMega with a single push button. If that's the case, no extra reset button is required for the AtMega, making a full system reset a lot more elegant. The theoretical approach to this is using the brown out detection (BOD) of the AtMega. If the AtMega processor is out for a number of milliseconds (disabled one way or the other), a restart is done by the BOD. When disabling interrupts and going in an eternal loop, a restart should done by the BOD also. This means that, if all goes well, and a button push is captured by an arbitrary chosen pin of the processor, bouncing effects can be eliminated by a software routine. Afterward, a reset signal can be send to the Z80 and finally, the AtMega can be forced in an uninterruptible eternal loop so the BOD will force the AtMega to restart also. Making sure that the AtMega doesn't restart the Z80 for a second time during the AtMega startup has to be taken care of during software development.
Last but not least, interrupt driven serial I/O must be combined with software address control logic for the Z80 and the memory, and with 4Mhz clock division and/or generation for the Z80. It looks like a number of functionalities will be so demanding that they will have to be written in assembler. However, the first software development will be done in a higher level language. Only if things turn out for the worst (functional or performance), assembler will be an option.
The PCB design is finalised after some initial errors (like a wrong estimation of the size of the EEPROM and SRAM IC's). Design rules checking (DRC) seems not to give any errors. The actual PCB can be found by clicking on the image to the right of this text.
The next step is to verify again if all components have the right size on the PCB (to be on the safe side). I have also cleaned up the traces to give the board a more structured view. Note that the VCC and the GND pins are not connected to paths, since the non-used space on the board is filled with GND on the top layer, and with VCC on the bottom layer. So the pins in question connect straight to these filled zones.
The design rules I've used for this prototype are
These design rules are fine for most of the PCB sellers. The choice of color depends on the PCB seller, as do the prices. But on general, one can find what one needs for a reasonable price on internet (especially if it's only for prototyping).
Finally, I can order my prototype PCB's. I'll have to make a userid at OSH Park. The way to deliver information to PCB sellers about the created PCB is variable in the sense that some accept KiCad PCB files, others accept only Gerber files that are given a specific name. Care should be taken not to make mistakes during the creation of the Gerber files, since this can lead to wrong PCB's, or at least (with companies that take the effort to check the Gerber files) to longer order delays. Since OSH Park accepts my KiCad PCB file, I'm saved on that point. However, they seem to have a problem with the connection points of the barrel jack at the top left of the PCB. I have decided to go through with this design and do some drilling myself on the prototype boards.
I have received a more realistic preview of what the PCB board will look like. I have checked all elements that can be verified, and everything looks ok. Can't wait to receive the actual boards.
The PCB's have arrived and are ready for testing. First, I've tested the PCB without any components on it, to see if all contact points, drill holes and tracks are doing what they are supposed to do. Then I've installed the components (apart from the IC's) on the PCB to test the circuitry of the passive components...
And of course, I've made a beginners mistake. The goal was to provide 5V stable power from an external power supply. And what does the schematic contain? A diode. And what does a diode has as side effect? It has a power drop voltage... So I've desoldered the D1 diode and replaced it with a wire bridge. Since the Zener diode also had it's consequences on the power supply to the IC's, I've eliminated that one too (both can be skipped on the BOM). That will give me enough space on the production version of my PCB to put a led/resistor in place that will show me if the board is powered, or to put a 6 pin debugWire connection to reprogram/debug the AtMega32 without removing it from the board.
While I was waiting for the prototype boards, I had planned to:
In short, the next two weeks would be all about 'testing development environments' and 'developing AtMega32 software'.
Challenge 1 Before testing how the AtMega32 behaves with the intended workload, one should be able to program it. The first idea was to work with an AtMega32 programmer and an USBasp device. Therefore, an 'external tool' has to be added to Atmel Studio.
Tools menu, one can click on
In my case, I entered the following information in the external tools dialog box:
Title: USBasp Command: C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avrdude.exe Arguments: -c USBasp -C "C:\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\gemma\avrdude.conf" -p atmega32 -P USB -B12 -U flash:w:$(ProjectDir)Debug\$(ItemFileName).hex:i
Unfortunately, when trying to do some development, it seemed that Atmel Studio was not able (understandably) to go into debugging mode for the setup in question. So that was that. I could develop without debugging possibilities and output data using only some led's, an oscilloscope and/or a protocol analyser, or I could find an other solution.
The solution I've found is the development of an own AtMega board, as I have already build for my AtMega328p's and for my AtTiny85's. This board connects Atmel Studio to an ATMEL-ICE programmer through an SPI connection. This works like a charm for the 328 and the 85 (well, it did some time ago anyway), so hopes are high that it will also work for the AtMega32. Just for information, I join a schematic and some pictures of my AtMega board for the 328 and the 85 on the right. Note that the reset button is disabled by removing the jumper, otherwise, the Atmel ICE can't use its debugWire features. Note also that the AtMega32 board will be more limited in the sence that there will be no flexibel power supply (only 5V) no jumpers, only one led (to show if power is on or of), and no reset button (only a pullup register). Further more, I'll have to look if I need an external crystal or if I can do the programming of the AtMega32 using it's internal clock. So, on the whole, it would be a barrel jack power supply, one led, a dip-40 15.24mm or even better, a zif socket, a 6 pin SPI interface, one decoupling capacitor, maybe an 8Mhz crystal and some breakout connectors.
The above, however, took me so much time that my other goals didn't make it on the agenda. And on top of that, I had the bad luck to brick 4 AtMega328's while trying to remember what the Atmel Studio development and debug steps were. My AtMega328 High Voltage Programmer has really earned back its cost big time!
Since my stock of AtMega32's is rather limited, I can't afford to brick my test IC's. Therefore, I've ordered a DIY High Voltage Programmer to debrick (reset the fuses) of an AtMega32. In the mean time, I'll continue to play around with Atmel Studio and some AtMega328's or AtTiny85's until developing and debugging AVR IC's will no longer end up with bricked IC's.
Challenge 2 will be looking into the speed of the AtMega32. Is this chip, clocked at 20Mhz, able to do all that I expect of it? More specific:
From now on, I will place the latest version of my code below this text. The date of the code is on top in the comment block, so it will be easy for the reader to see if things have changed. Note that, as the comments say, the goal of this code is not to win a beauty contest, but to live up to the expectations of minimal clock cycle use per activity. Therefore, some compromises are necessary, not in the least on the domain of splitting up the code in functions and subfunction. Each interrupt, each jump, each call takes time that can be spent to more usefull activities.
Since it is clear that in the end, assembly will be the preferred language, I have decided not to use C at all. So I restarted a new Atmel Studio project, bricked my AtMega again several times before the entire configuration was stable and started to create a canvas in assembly. I count on programming kind of structured in the beginning, and decide afterwards where I have to give up the structure in favor of speed.
My first idea was: "Since the AtMega328 and the AtMega32 are very similar, I can do my testing with an AtMega328 @ 16Mhz external clock. If I can do what I want to do with this setup, there will be no problem with the AtMega32 @ 20Mhz external clock". However, after developing the Z80 Clk signal routine, I decided to switch from programming a real device to using the Atmel Studio Simulator for the initial development. It's a lot less hassle with cables, programmers, power supplies and it's less error prone during debugging.
In the previous versions of Atmel Studio, the simulator had a number of annoying bugs that seem to be solved in the actual version. So, after a first version of the assembly code for the AtMega328, I've changed to a version for the AtMega32 (which is functionnaly compliant with the AtMega32A).
An other advantage of the Atmel Studio Simulator is that there is an option to simulate the external clock frequency, including a cycle counter and a stop watch. These two together will permit me to do effective simulations and to draw a first indicative timing diagram of the functionalities that I have to develop.
The use of Atmel Studio Simulator tought me that the AtMega32 has a number of disadvantages. The most remarkable are the lack of possibility to trigger an interrupt when digital input pins toggle state, and that its second 8-bit timer only has one channel and hence other names for programming its ports. So I switched, after looking in the datasheets, to an AtMega644p. This one seems to be more compliant with the AtMega328 and doesn't has the disadvantages of the AtMega32. On top of that, the AtMega644p exists in an AtMega644p-20pu version (20Mhz clock) and has 64Kb of Flash memory. The latter could be very usefull if I decide to use the AtMega not only as a utility IC but also in replacement of the eeprom (reduction of the PCB size with 1 dip40).