Close
0%
0%

A 4$, 4ICs, Z80 homemade computer on breadboard

No iron, no cry! Simply wire it to build a mini 4MHz Z80 64kB RAM system with a Basic interpreter as an educational technological puzzle!

Similar projects worth following
This is the Z80-MBC (Mobile Breadboard Computer), a mini 4MHz Z80 64kB RAM system with a Basic interpreter and that can be easily expanded. It has an "Arduino heart" using an Atmega32A as an "universal" I/O emulator. And can be used and powered with a tablet or smartphone too...

During some surfing on Ebay I realized that with 4$ it is possible to buy enough ICs to build a complete Z80 system that can be done using a breadboard, and taste some flavor of retro computing.... So I did it and here it is the story!

Here is a video with the Z80-MBC in action:

and here with a smartphone (so it is explained the word "Mobile" in his name...) with a common OTG cable (the various test clips in this video were used for some measurements with a Logic Analyzer):

* * HARDWARE OVERVIEW * *


The needed ICs are:

  • Z80 CPU CMOS (Z84C00) 4Mhz or greater ($1.16)
  • Atmega32A ($1.70)
  • TC551001-70 (128kB RAM) ($1.10)
  • 74HC00 ($0.25)

Total cost: $4.21

The wires were taken from salvaged broken LAN cables, and the other components were salvaged from others unused breadboards.

The schematic is attached in the Files section. The MCU Atmega32A is used as universal I/O subsystem, as Eeprom, and as reset and 4MHz clock generator for the Z80 CPU.
Into the Atmega32A it is flashed an Arduino bootloader taken from here , and it is possible to use the Board Manager of the Arduino IDE for that.

Flash the Arduino bootloader at first (with the method you prefer), next you can start to build the whole thing!


Of course I used the Arduino IDE to develop the IOS (I/O Subsytem) that interacts with the Z80 bus and "virtualizes" the peripherals seen by the Z80 CPU.
As oscillator it is used the internal 8MHz Atmega32A oscillator, so no quartz is needed, and from this one is derived the 4MHz clock for the Z80 CPU (so the "Internal 8MHZ osc." bootloader variant must be chosen when flashing the bootloader from the Arduino IDE!).


The 74HC00 is mainly used as RS flipflop to stop the Z80 CPU during I/O operation, giving the needed time to the Atmega32A to interact with the Z80 bus.
The 128kB RAM TC551001 is used only for half (64kB) because the Z80 address space is only 64kB (I've chosen this IC for the low cost).
Note that only the CMOS version of the Z80 CPU can be used here. This because only CMOS version, under given condition that are respected in this schematic, has logical levels compatibles with Atmega32A and 74HC00.


NOTES ABOUT THE COMPONENTS:


You can use any Z80 CMOS speed grade, because the lowest is 4MHz.
The Atmega32A can be substituted with an Atmega16A, I've chosen the first one just to have enough space for future upgrades.
The 74HC00 can be substituted with a 74HCT00 if you already have one.
The RAM chip TC551001-70 can be substituted with any suitable 64kB RAM (do not use < 64kB RAM).
The USER led (D5 in the schematic) MUST be blue or white just to be sure that V(forward) is >= 3V.


Here is a video that shows a simple basic program that interacts with the "USER led" and "USER key":



On the breadboard there are others status led: the HALT led turns on if an HALT instruction is been executed and the Z80 CPU is in a Halt state, the DMA led turns on during DMA operations when the Z80 bus is in Hi-Z, the IO_OP led turns on when the Z80 CPU is accessing a I/O virtual device "emulated" by the Atmega32A (as the serial port), the LED_D0 led is the classical "Arduino" led (that one connected to D13 pin on the Arduino Uno) that here is connected with the Arduino D0 pin and is turned on normally as a power on indicator.


The serial port SERIAL-USB (see schematic) can be connected with a TTL-RS232 adapter, or with a serial-USB adapter.
I've used a serial-USB adapter that acts also as power source for the Z80-MBC, and has the DTR signal for the "autoreset" driven from the Arduino IDE. For a terminal that has a serial TTL port no adapter is needed.


In the schematic there is also the IOEXP port to expand the I/O capabilities, i.e. adding GPIO ports or a RTC for future expansions.



* * SOFTWARE OVERVIEW * *


I've "ported" the Basic interpreter to the Z80-MBC using the sources provided in the great Grant Searle site , after the needed modification due the different HW design. In the...

Read more »

A041116 KiCad4 Files.zip

Z80-MBC KiCad4 Project Files

Zip Archive - 37.14 kB - 01/08/2017 at 09:12

Download

basic.asm

Z80-MBC Basic interpreter

x-asm - 196.93 kB - 01/04/2017 at 14:27

Download

S121216.asm

Z80-MBC uBIOS

x-asm - 8.63 kB - 01/04/2017 at 14:27

Download

S091216.asm

Z80-MBC Loader

x-asm - 2.79 kB - 01/04/2017 at 14:26

Download

A041116 schematic.pdf

Z80-MBC schematic

Adobe Portable Document Format - 101.42 kB - 12/17/2016 at 13:46

Preview Download

S221116_Z80_Breadboard.ino

The sketch for the Atmega32A

x-arduino - 64.17 kB - 12/17/2016 at 13:36

Download

View all 6 files

  • SOFTWARE INTERNALS: The boot process

    Just4Fun01/04/2017 at 14:35 0 comments

    Here is a description of the two phases boot process and the sources of the Loader and the uBIOS + Basic (as requested by some people).


    At power on, the Atmega32A uses a DMA access to SRAM to copy the loader in the upper memory address space.
    Because the loader is small, only a limited number of address lines are requested, saving some GPIOs for others tasks.

    When the Atmega32A completes the DMA loading phase (first phase), it releases the Z80 bus and resets the Z80 CPU that starts to execute the loader from SRAM starting at address $0000.


    Then the loader relocates itself at the bottom of the memory address space and it loads from the Atmega32A (this time used as a "virtual" sequential ROM in the I/O address space) the uBIOS + Basic image (second phase).

    After this second load phase it jumps to the starting address of the uBIOS + Basic image, and executes it.

    Inside the Arduino sketch you can see the two hex arrays. The smaller one is the Loader image, the bigger one is the uBIOS + Basic image.


    In the Files section I've added the Loader source (S091116.asm) I wrote from scratch, and the two files (uBIOS and Basic) I took from the Grant's site. I've modified the first one (the one I've called uBIOS) that contains the I/O routines due the different HW design. In particular I changed the I/O addresses, the init code made for the original ACIA and the code to menage the internal registers of the ACIA. I've changed also the code that manages the ACIA serial handshaking because not needed here (the serial is managed inside the Atmega32A by the Arduino bootloader "environment") . You can easily see any modification in the source (S121216.asm) because they are marked with the string "Z80-MBC:" in the comment.

    I left the Basic interpreter (basic.asm) untouched (for now, until I need some custom commands...).

View project log

Enjoy this project?

Share      

Discussions

Bill Westfied wrote 2 days ago point

Starting to look relatively real!

Three mistakes so far: two missing pull-x resistors, and a signal trace that collided with a power trace :-(   Nothing too difficult to repair, though!  Still waiting for chips (and it turns out I hadn't ordered them when I thought I had...)   I also bugged Atmel for some samples :-)

  Are you sure? yes | no

Just4Fun wrote 2 days ago point
Hi, I've seen that you added a couple of power connectors... good idea...
On the back side (your previous photo) it seems to be some SMD capacitors on it. Do you have added more bypass caps?

  Are you sure? yes | no

Bill Westfied wrote a day ago point

Yeah. For personal/hobbyist PCBs, I like to put SMT bypass caps on the back of the board (where they usually fit pretty easily) as well as TH caps on the front. That way you can populate with whichever you happen to have on-hand (if you're like me, at some point you bought a "near infinite supply" of some type of bypass cap...) It doesn't hurt that this also means you can do "extra" and "multiple value" caps "if needed."

  Are you sure? yes | no

Scott wrote 7 days ago point

I like this  design.  I had to take a few minutes to see how the bootloader works; 1) AVR copies the bootloader to Z80 RAM then 2) the Z80 bootloader xfers the BASIC image from the AVR to RAM on its own.  I see an 'HC00-Flip-Flop to force a wait condition while the AVR responds to "I/O" requests.  That's a simpler method than I am using. :)  Using that method, do you know what the latency time is for the Z80 to make an I/O request till the time the AVR responds with data available on the data bus?

I am presuming this is a "proof of concept design".  Do you have intentions of going further with it? i.e. adding more I/O?

I am working on a similar design using a TEENSY++ 2.0 as the host controller.  https://z80avrproject.wordpress.com/  Using a 16MHz AVR, the Z80 clock can be as high as 8MHz (using an OCx output).  I was looking forward to the end design goal, which is to use an SDcard as a "disk drive" (or drives) for the Z80 (CP/M), the TEENSY as a TTL-2-USB bridge and and "system monitor".  I have intentions of implementing a software debugger as well since there doesn't seem to be any available except via the software emulators, which sometimes do not work with all code.  I wanted to read all 16 bits of the address bus, for memory test, etc. and the AT90USB1286 on the TEENSY does not have enough I/O to access all address, data and Z80 control lines so I use a 74HC299 as a bidirectional data bus expansion interface and two 8-bit ports for the upper and lower address lines.  

Thanks for the effort!

P.S. Bill Westfield; any extra PCB's available?

Peace and blessings,

Johnny Quest

  Are you sure? yes | no

Just4Fun wrote 7 days ago point

Hi, I'm glad for your question. You are the first person that focused the * main * aspect of this thing: how the AVR interacts with the Z80 bus! In fact there is a double "hidden" trick that makes the whole thing working!!! (I mean hidden "inside" the schematic...), and the FF is only a little part of it. Explain all the "process" is a little complex and can't be done here. I'll make a "log" on this theme (as I did for the boot process), but it require some time to prepare some theoretical timings to explain it.

I'm currently working on a GPIO expansion (HW 80% done, SW 0% done) , so this it shall be the next thing. I'm just starting now to study the CP/M porting....

There are a lot of improvements that can be done.... may be a "boosted" version (but not on breadboard....).

I do this in my little spare time... so this is the limit....

  Are you sure? yes | no

Scott wrote 7 days ago point

Hi:

Thanks for your reply.

I am not sure if you had a look at my project.  The difference in our two methods of using the AVR as a "host (I/O) controller" are slightly different.  In your case, any access to I/O space triggers the WAIT F/F, thus holding the Z80 in a perpetual WAIT state until your AVR can service the request.  That certainly simplifies the timing.  If I am not mistaken, your AVR also initiates a Z80 IRQ and tosses an IRQ vector on the data bus, yes?

And yes, my original breadboard version got complex very quickly, which is why I decided to cut a PCB. :)  No doubt, you are likely at that stage as well. :)

In my design, I wanted to keep the AVR in SLEEP mode and only wake it from SLEEP when it is needed, thus conserving power since the intention is to use the USB connection for power and being limited to ~500 ma max.  The AVR data sheet states that the AVR needs ~5 clock cycles to service an external IRQ (INT0).  In testing with a logic analyzer, I found that at 16MHz, the AVR IRQ service routine needed about 14 cycles (875nS) maximum to respond and set the WAIT line active, hence the programmable WAIT state generator design to force a WAIT condition until the AVR can respond.  This of course varies depending on the clock speed of the Z80, which is also programmable via the "host controller" as is the number of wait-states.  

That's the reason for my question concerning the response time of your AVR once a WAIT state is asserted.

Since the wait-state generator is contained within a GAL22V10, I may look into implementing a simple F/F as you did.  It may be easier to work with and would not require setting "X" number of wait-states depending on the Z80 clock speed.

I like your use of the larger RAM chip.  I had about 20 pieces of the 32Kbx8 RAM on hand, so they made their way into the design.  But a single RAM takes less PCB space and fewer trace runs.  It also allows bank-switching, which I see you are not implementing in your current design. I/O pin limited, eh? I know the dilemma. :)

I noticed you are using the internal 8MHz oscillator on the AVR.  Since timing is not critical in the case of your design, that makes sense.  If speed becomes an issue, the AVR is rated to 20MHz at 5 volts, which would reduce your response and servicing time by about 60%.

What you are doing with your Z80 bootloader and the AVR as a sequential ROM dumper are the equivalent of what I am planning to do with the SDcard interface.  Of course, I'll need to modify a custom CP/M BDOS for it to work with the AVR/SDcard interface.

I have the hardware finished on my project and have performed some preliminary hardware testing but I have spent the last several weeks on another parallel project I am working on, so the Z80 SBC progress has fallen a bit behind. :(

On the GPIO, is that something you are planning to do with the I2C interface?  Perhaps using one of the PCF8574's?  For CP/M, you might look into the DS3231 (I2C interface) as a Real-Time Clock for date/time stamping.  eBay has modules with a battery for about US$1.25.

How are you testing your Z80 code?

What are you using for your Z80 assembler?  I tried Z80ASM and Z80-ASM under Linux and both failed to assemble your source code.

If you are like me in this respect, taking a step a few decades back in time to to the days of the Z80 is certainly another learning process.  Adding to that the AVR "technology" and mating it with the Z80 is another learning process, not to mention eventually delving into the internals of the CP/M source code but I find the challenge in hardware and software rewarding. :)

Looking forward to seeing more progress on this design.  Thanks again for sharing.

Peace and blessings my friend,

Johnny Quest

  Are you sure? yes | no

Bill Westfied wrote 4 days ago point

>> P.S. Bill Westfield; any extra PCB's available?
I had 10 made; I've got some local people that might be interested, but there might be one or two left over.  If they work, I'll be posting the CAD files.  Though they're a bit big to be economical on OSHPark, and PCBWay/etc will give you 10 boards at a time.

I thought the IO mechanism was obvious (which makes it elegant!) - is there more to it than going into continuous wait states on any IO request?  You should be able to plug in "more complicated" devices where the AVR is now, and use the same mechanism.  Probably even paralleled m32's that each only respond to "their" part of the io address space...   And it should work on other chips that use a similar wait-state mechanism (8085, 6800, 6502, 6809...) (but memory mapped IO will make some aspects harder...)  (And I haven't thought further than IO plus "boot state."  Interrupts might be complicated as well.)

  Are you sure? yes | no

Scott wrote 4 days ago point

Hi Bill:

Thanks for your reply.  I sent you a private message on your PCB's.  

I looked at pricing for  OSHPark and thought they were expensive.  I also looked at PCBway and they're a little high as well.  For my Z80 SBC and 8052 SBC projects, I went with http://youpcb.com . 10 pieces of a 3x4 inch, 2-layer PCB was US$41 total ($22 + $19 shipping).

On your thoughts about using the AVR host controller as a more complicated I/O device, that's my intention, to use the AVR as a "virtual peripheral", or multiple "virtual peripherals".  I plan to emulate an i8051 or MC6850 UART and *maybe* an i8072 FD controller, depending on how I modify the CP/M BDOS.   

The AT90USB1286 used on the TEENSY++ 2.0 has built-in USB hardware, so it can be programmed to be a "CDC compliant" serial-to-USB bridge with little effort.  I see no reason why the Mega32 used on this project cannot do the same.  If code space is a problem, the Mega644 and Mega1284p are pin-compatible drop-in's for this project (and yours).

I am looking forward to seeing where the author takes this project ... and where you will go with it.  :)

Thanks for sharing.

Peace and blessings,

Johnny Quest

  Are you sure? yes | no

Bill Westfied wrote 3 days ago point

The PCBs arrived today.  Rather quicker than I expected - I'm still waiting for parts...

PCBWay was having a "special" $10 for a 10x10 board (plus ~$20 shipping),  so these ran me about $3 each.  OSHPark is great for tiny boards, but gets expensive rapidly as the board size increases (which is fine, and exactly the way I normally want things, but it doesn't work out well for this board.)

  Are you sure? yes | no

legacy wrote 3 days ago point

I have these 8051 boards(1) for sale. Classic design with CPU, ROM, RAM, UART. Maybe someone can be inspired by their design.

(1) http://www.eevblog.com/forum/buysellwanted/(fs)-8051-board-with-isa8bit-bus/

  Are you sure? yes | no

Just4Fun wrote 3 days ago point

Bill, you are now the "Official" PCB designer of this project.... :-)

  Are you sure? yes | no

Bill Westfied wrote 3 days ago point

Ahh.   I see.  In addition to the flip-flop to add wait states, you need to do a little dance coming OUT of the wait state so that the AVR continues to drive the bus long enough for the Z80 to read data (assuming an IO Read), but not so long as to be driving the bus when the z80 does it's NEXT access.  Annoying.  Essentially equivalent to enforcing Thold on an actual device...
Is that actually needed on IO Write as well?  The AVR isn't driving any pins in that case...

  Are you sure? yes | no

Just4Fun wrote 3 days ago point

Yep... You cought it!... But there is also an other "side effect" to manage.... So it's needed for WRITE too...

  Are you sure? yes | no

esot.eric wrote 01/11/2017 at 05:44 point

Cool. Why didn't I see it before? AVRs are chock-full of peripherals, so use one as a peripheral/I/O/DMA controller. Wonder just how many ICs you saved from a similar-functioning old-fashioned system. Nice labels on the topsides of the chips, too.

  Are you sure? yes | no

Just4Fun wrote 01/12/2017 at 07:35 point

Thanks!

  Are you sure? yes | no

Bill Westfied wrote 01/08/2017 at 08:05 point


So... I've copied (most of) your PDF schematic into EAGLE and had a try at PCB:

I've got a couple of questions:

1) Why 9 address lines between the Z80 and m32?  A Z80 bootloader could be copied into RAM in far less than 512 bytes, assuming all it had to do ws load a bigger bootloader via IO.  And you might not even have to implement all 256 IO ports, since they're potentially "intelligent" enough that you don't need 32 bytes of address space to implement a uart.  (I might be trying to free enough pins for the m32 to do video...)

2) You mentioned that the m32 loads the bootloader into "high memory"; doesn't it only have access to low memory?  A9..A15 are pulled low, right?

3) Why the funky setup for the USER led and switch?  Aren't there simpler schemes for using a single pin for both input and output?

  Are you sure? yes | no

Just4Fun wrote 01/08/2017 at 10:12 point

Wow... great!! Here the answers to your questions:

1) Yes, you can use less address lines. I left 9 lines in this HW version just to be sure to have enough space for any SW update. In a next HW revision probably I'll lower them. The actual Loader (S091216) is 57 bytes long, so 6 address lines should be enough for now, also for the I/O address space (up to now the used I/O address are from $00 to $02, as you can see in the sketch).

2) Memory starts from $0000 to $FFFF. I call "upper memory" that one is at beginning, so $0000 is "upper"...

3) May be... If you find a working simpler way please tell me...

PS: please post a photo when you build it!

  Are you sure? yes | no

Bill Westfied wrote 01/09/2017 at 23:48 point

Final-ish version.  Does anyone have comments?  It's a very conservative PCB (smallest tracks 0.3mm), designed to fill up the 100x100mm PCBs that China produces so cheaply...


(Edit: "final" silkscreen, sent to PCBWAY)

  Are you sure? yes | no

K.C. Lee wrote 01/10/2017 at 00:05 point

You should keep the silk screen (Z80) away from the solder pads in your proto area.  Some PCB vendors might remove it and some might not be so careful.

Also check your silk screen font sizes as they may or may not be visible. I usually thicken them and I know what line width and sizes I can get away from my supplier.

  Are you sure? yes | no

Bill Westfied wrote 01/10/2017 at 00:56 point

Yeah; I was hoping it was masked, so I'll end up with white between the pads (like some of the Olimex boards.)   But results are likely to be vendor dependent.
The text and lines you see are post-widening.  They should be at least 8mils wide...

  Are you sure? yes | no

K.C. Lee wrote 01/10/2017 at 02:01 point

8 mils is a bit too thin for my PCB vendor.  On Eagle, I use 24 mil tall text and change the ratio at least to 15% and even then they failed me. 24 is a bit small.

I avoid having silkscreen any where near my pads in general as the silkscreen alignment is not reliable from my supplier.

https://hackaday.io/project/4993-dual-channel-battery-chargeranalyzer/log/17291-keeping-up-with-the-times-prototyping-with-qfn-and-bga

Just something to think about.

  Are you sure? yes | no

Bill Westfied wrote 01/10/2017 at 02:46 point

The ratio is the text line width to text size.  If you had 24mil text with a ratio of 15%, then the line width would have been less than 4mils!  In any case, most of the "small" text on this board is 50mil high with 16% ratio, which should be 8mil for the lines making up the text...  (100mm is a relatively large board; things are bigger than they look in the picture (as opposed to when you're trying to fit things in a 50mm board, and things are tinier than you expect.))

  Are you sure? yes | no

K.C. Lee wrote 01/10/2017 at 03:49 point

I pack my boards very tightly - on dense boards about 80% of the surface area are filled advantage of those deal.  There isn't usually a lot of empty space for silk screen artwork etc.  FYI see my projects.  Hard to judge the scales as I work in 1 mil grid and mostly fine pitched parts.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 01/10/2017 at 04:09 point

Hey that's awesome !

  Are you sure? yes | no

Just4Fun wrote 01/10/2017 at 10:17 point

Hi, just to say I'm currently working on a 16x GPIO Expansion Module. I think that it can be fitted inside your PCB too... It's only a DIL28 IC, some passives and two headers, and can be an "optional" hardware to assemble on it. You decide... (if you are interested I can preview the schematic draft).

  Are you sure? yes | no

Bill Westfied wrote 01/10/2017 at 11:03 point

There's room for a 28pin DIP in the prototype area.  Does it connect via the I2C?
I think I need to get PCBs made and build this thing before I decide that it's not such a good idea, after all.  :-)

  Are you sure? yes | no

Bill Westfied wrote 01/10/2017 at 11:04 point

Hmm.  One "problem" is that the board exceeds the 80x100 size limit of "free" EAGLE.  The main guts would probably fit in 80x100; the prototype area would go away :-(

  Are you sure? yes | no

Just4Fun wrote 01/10/2017 at 11:26 point

Yes, it connects via the I2C, and it can be easily assembled with the prototype area too...

About the Eagle limit, may be it's time to give KiCad a try... :-)

  Are you sure? yes | no

Bill Westfied wrote 01/13/2017 at 01:01 point

Parts ordered, gerbers sent off to PCBWAY's $10 special...

  Are you sure? yes | no

Just4Fun wrote 7 days ago point

Great! 

  Are you sure? yes | no

Scott wrote 7 days ago point

Bill:

Any extra PCB's available?

  Are you sure? yes | no

marcelo wrote 01/07/2017 at 15:56 point

Hi, Is possible share the Kicad schematics ?

  Are you sure? yes | no

Just4Fun wrote 01/08/2017 at 09:15 point

Said and done! I've just uploaded all Kicad4 project files in the Files section...

  Are you sure? yes | no

marcelo wrote 01/08/2017 at 16:07 point

Great ! thank you my friend 

  Are you sure? yes | no

Scott wrote 01/03/2017 at 08:50 point

Hello:

Nice project.  I agree with Franz; will you release the bootloader, uBIOS and modified BASIC source code? 

Peace and blessings,

Johnny

  Are you sure? yes | no

Just4Fun wrote 01/03/2017 at 13:45 point

Hi, as I said to Franz, just wait some days...

  Are you sure? yes | no

Scott wrote 01/03/2017 at 18:47 point

You must have been posting while I was, thus I was unable to see your response to Franz.

Thanks!

  Are you sure? yes | no

ekaggrat singh kalsi wrote 01/02/2017 at 23:39 point

is there a way to hookup a 3.5/4.2 inch lcd  and keyboard directly? that would make a great pocket retro pc

  Are you sure? yes | no

Just4Fun wrote 01/03/2017 at 13:57 point

With "some" HW and SW chamges yes...

  Are you sure? yes | no

Franz Zinn wrote 01/02/2017 at 20:13 point

Would you be able to share the modified software source code (or orginal and patch) and a brief explanation of the modifications ?

  Are you sure? yes | no

Just4Fun wrote 01/03/2017 at 13:44 point

Ok, no problem at all... I'll do an update next days on this topic.

  Are you sure? yes | no

legacy wrote 12/20/2016 at 20:38 point

bluetooth with a smartphone? Useless as a brick, you can not type comfortably, whereas the idea at the basis of the DMA is brilliant. My 50 cents.

  Are you sure? yes | no

legacy wrote 12/20/2016 at 20:40 point

Also, I hate the price list when things come from China.

  Are you sure? yes | no

qquuiinn wrote 12/18/2016 at 02:18 point

Cool project! I like the idea of using it 'headless' over bluetooth with a smartphone, it really makes a more practical retro SBC instead of relying on old CRT displays and PS/2 keyboards like other ones I've seen. 

  Are you sure? yes | no

Does this project spark your interest?

Become a member to follow this project and never miss any updates