Products > Vintage Computing

Need some advice on threading on a Z80

(1/6) > >>

Hey everyone,

I've been working on a totally custom Z80 computer project on and off for a while, but here recently I've really dove into it!
It is a modular design and will ultimately end up with cards on a backplane (rc2014 style with a dumb backplane). CPU card, serial card, video card, etc.

So I'm at the point where I need to make some decisions with my software and hardware philosophy before going any further.
I think I will make each discussion a separate thread because these are things I haven't seen discussed elsewhere and might end up being useful to someone in the future.

So to avoid an XY problem I will state my end goal. I am building a "real" kernel (as real as you can get with this old CPU) with a "true" OS sitting on top of it. I'm doing a filesystem (likely FAT16 to save me a headache), syscalls, everything.

While I was building my video circuit it hit me... if I hope to ever do a GUI with mouse and windows and etc, as slow as it might be, I will pretty much HAVE to have threading.

I've been doing a ton of reading and messing with some code and threading isn't really that tough to implement. My hang up is the rate in which I interrupt the Z80 to make it swap threads.
Everything I've found on the topic never mentions the frequency in which they swap threads, so I really don't know where to start. It just seems like an arbitrary number...

I'm all torn between using Mode 2 Interrupts and just a regular ol' Mode 1 interrupt as well. I've kinda hit my budget limit on this project for now and so any Mode 2 stuff will have to be emulated with an AVR chip or something. I'm trying to keep my AVR "cheating" to a minimum and only use them when finding some old school ICs are difficult or expensive (like PS/2 or video controller ICs). This is actually going to be the topic of my next thread, emulating the Z80 Mode 2 interrupt "protocol" with AVR chips.

I'd love to hear any ideas you all have.


Consider an alternative: cooperative multitasking.

At any/every convenient point the task calls yield(), the PC "disappears down the plughole", and reappears up the plughole of whatever thread's yield() function is appropriate.

Easy to implement, avoids all sorts of problems - except that of an overly greedy thread.

Apart from that, if you really want to force swaps, then I'd say >=10ms is not unreasonable on a "real original" Z80. Unless there is reason to choose another interval, of course. By "real original" I mean running with a 4MHz(?) clock, not a Z80 ISA implemented in an FPGA. From memory, a contemporary 6800 calculating a floating point sine/cos pair would take around 30ms.

You might find it helpful to look at the old multi-process MP/M operating system.  It ran on 8080 and Z80 CPUs.

MP/M user manual:

It used to be a commercial product, but long ago Digital Research released the source to it, CP/M, and a bunch of others:

To answer your specific question regarding system tick, they recommend 16.6ms or 20ms (60Hz or 50Hz).  Reference on page 106 in the above user manual.

My Z80 is a 10MHz CMOS version, but I intend to make sure my build is built with 4MHz in mind, at least at first! I might use the 10MHz clock later to do see how far I can push things!

I'm pretty new to Z80 ASM, how would cooperative multitasking look in software on a high level?

That sounds like I would have to code all of my programs to yield, instead of being forced by an interrupt. I'm not sure how that would look in the code...

I had a rough plan for my threading where I would also set some flags in memory for each thread to tell the system how to prioritize. For example, if the IO-heavy flag is set then we can prioritize those threads so that the CPU-heavy threads don't dominate and the IO thread just sits around.

Wrapping my head around this stuff has been challenging but that's why it has been so fun!

Oh thank you for these links! I've been googling quite a bit about this topic and haven't came up with much. I'll dive into these and take a look!

If I were to build a kernel and an OS on top, which is entirely a software exercise, then I would use something else than a Z80.  Back in the days of the Z80, the programs and the OSs for it were single user and single task.  You can improvise and mock some more recent features, but Z80 has no hardware support, only an interrupts vector table and a single non maskable interrupt at a fixed address.  IIRC, NMI is triggered by an edge, while INT is active while asserted, so you may lose interrupts or overflow the stack if you don't handle disable/enable interrupts inside the interrupt routines.

If I were to build a Z80 computer, which is a hardware project with some OS needed to make a use of it, then I will port the CP/M OS to my hardware.  CP/M was an OS before MS-DOS and has 3 components:  CCP, BDOS and BIOS.

To port it, you will only need to modify the BIOS, which is very small, about 10 functions or so, don't recall exactly the number, but they are very basic, for example put a char on the screen, or read next key, or write a sector to disk, things like these.  The BIOS in CP/M plays the role of the hardware abstraction layer, similar with the drivers from Linux or Windows.

If you write those few BIOS entries, then you will suddenly have a fully functional computer, with keyboard, display, serial port, printer and disk (including a file system and console commands, e.g. a DIR *.c will just work).

Even more, this will guarantee all the existing CP/M tools and programs will work:  C compilers, Basic interpreters, databases, debuggers, assambler/disassembler, disk editors, all the tools to check and repair disks, intercomputer files exchange (like Kermit), and all the text games and the programs ever written for CP/M will run just fine on your Z80 computer.

CP/M programs are easy to find online these days, many with sources too.  I remember CP/M was donated to the public domain some years ago, with complete sources and documentation, so it would be possible to change a few well documented BIOS functions, then cross-compile all on a contemporary computer.  Doable by a single person, and in a reasonable amount of time.

Then you can add mouse features to CP/M, as a software exercise (there was no mouse in the standard CP/M, so yours might become a nice contribution to an historic OS).


[0] Message Index

[#] Next page

There was an error while thanking
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod