Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
SymbOS Z80 multitasking operating system (symbos.de)
182 points by jbverschoor on Dec 22, 2023 | hide | past | favorite | 69 comments


Related:

SymbOS: Graphical Z80 Multitasking Operating System - https://news.ycombinator.com/item?id=16078915 - Jan 2018 (98 comments)

SymbOS: preemptive multitasking OS that can play mp3s, video on 8-bit Z80 PCs - https://news.ycombinator.com/item?id=10749206 - Dec 2015 (36 comments)

Z80 Symbos OS now has networking support on MSX - https://news.ycombinator.com/item?id=9634634 - May 2015 (25 comments)

SymbOS: preemptive multitasking OS that can play mp3s, video on 8-bit Z80 PCs - https://news.ycombinator.com/item?id=4653232 - Oct 2012 (1 comment)


Congrats on taking this concept far beyond 'proof of concept'; well done.

Done many years ago now, there is a preemptive multitasking OS for the Z80 for the "kiss TNC" used in ham radio: https://github.com/cheponis/KISS-TNC2/blob/master/KISS-TNC.a... This only used the interrupts to permit the modem (receive) side to generate interrupts, but the concepts are the same as if the interrupt would have come from a timer source. Yes, it uses the EXX and EX AF,AF' instructions.

The best Z80 book, which describes the little-known W and Z registers is http://www.z80.info/zip/zaks_book.pdf start on page 86 for their description.


I'd be very interested to know how preemptive (rather than cooperative) multi-tasking is implemented. It's been a while but I don't remember the Z80 having any suitable primitives upon which to implement preemption.

I poked around the website but it seems light on implementation details. Super-impressive piece of work though.

Edit to say: thank you to the responders who've backfilled the gaps in my memory. Interesting what you forget given enough time.


I once implemented a pre-emptive kernel and OS on a very crude hardware, the Hewlett-Packard Graphing Calculator HP48GX, running a Saturn CPU (4Bits with 64bits registers, a weird beast).

It can still be downloaded here : https://www.hpcalc.org/hp48/apps/shell/

You don't need MMU or anything of the sort.

The only thing you need is programmable interrupts.

My implementation was using a 64Hz timer, that was also synchronized on the LCD screen "vsync" as it had to be serviced for kernel-level double buffering and different modes of simulated multiple grey levels.

It is much less difficult than it seems, save registers, save context, load context, load registers, return to the current process.

Optimizing the code is just a good knowledge of the CPU constraints and bit of juggling with registers. It was a simpler time, you could benchmark code by counting cycles, instruction by instruction. No cache, no branch predictors, no throttling.


I did something similar on the C64 (6502). Programmatically user code could mask interrupts, but as long as it didn’t it worked fine. It saved all the registers and restored them prior to switching execution threads. The unified memory space required that each thread ask for an absolute memory offset to be allocated and then voluntarily stay in that space.


The vertical blank interrupt was how many games did their screen updates and played music.

Those were good days writing demos and crack intros.


Z80 has a non-maskable (NMI) interrupt line that will break whatever code is currently executing without allowing the software to opt out (EI/DI instructions), and then jump to a hardcoded page zero location, I believe it is address 0x66.

This line is typically tied in popular Z80 machines to the vertical blanking generator (frame refresh - 50/60Hz). Presumably, the OS would then schedule the tasks in a round robin fashion and most tasks will cooperate and yield control quicker to allow a not too choppy experience.


> Z80 having any suitable primitives upon which to implement preemption.

In general the only thing needed is an external interrupt (which the Z80 has). All but the cheapest deeply embedded 8 bit micros will have one and therefore can support preemption.


As other people have said, there's an NMI line. But that's not usually how it's implemented because you tend to want to mask it if the thing is doing a real time or time critical task. The Z80 CTC was the canonical solution.

Back in the dark ages had an "OS" which had a simple "task table". This was a circular linked list with enough space after each pointer to store the CPU state for a task and some stack. There was one element per task. The task interrupt would fire every 100ms, the registers/stack pointer/PC would be dumped to that, the list followed and the next task picked up and loaded into the CPU, then it'd return from interrupt and off it'd go again. You could call YIELD at any point if you didn't want the rest of your time slice. If you had something that needed to handle an interrupt from the CTC or an NMI, it would disable interrupts until it was done.

Notably you didn't tend to create new tasks. They were hard coded in at assembly time!

Edit: we also had an 8031 version as well.


Thanks. Back when I last wrote an z80 asm I didn't have access to an environment with anything like an os.

> Notably you didn't tend to create new tasks. They were hard coded in at assembly time!

Reminiscent of the "executive" in the Apollo lunar module computer.


Even DRI's MP/M from 1979 had preemptive multi-tasking, as long as the platform supported an clock interrupt.

You can find the documents on bitsavers, the binaries may well be there and/or on Gaby's site.


There was a program called Switcha published as a listing in Your Sinclair. You could make a 48K Sinclair Spectrum appear as three 16K machines. It installed an interrupt mode 2 handler and checked for a key combination to swap out the lower 16K of RAM. No reason it couldn’t have time sliced them.


What a time to be alive, 1980s pdf at your fingertip¹. The tool is described on page 84 of the linked doc.

¹ https://ia903206.us.archive.org/19/items/Your_Sinclair_003/Y...


Thanks! I remember that cover now! The article has both the hex and the asm listing. I think I did an update to it to use the bank switched memory on the 128K to get 8 16K Spectrums.

Of course with something like a MGT +D with the 8K ROM and 8K SRAM it would have been possible to use the NMI button to switch between two 48K Spectrums on a 128K and have them run a game in one and BASIC in the other.


Z80 has a mirror register set that can be swapped immediately. That makes task switching faster.


For up to two tasks


No, for kernel code that handles the switching.


EXX doesn’t transfer to RAM, only to the ‘ register set. Great for ISRs (as long as you can single-thread the interrupts) but you’re not going to track task state using it.


That's what I said. You can make the kernel's code that handles the task switching faster that way.


> Z80 has a mirror register set that can be swapped immediately. That makes task switching faster.

Your original statement is sufficiently ambiguous that non-mind reading people might interpret it to mean “all tasks”.


They’re not claiming protected mode multitasking.


Yeah they don't have protected mode. They are working on a language+toolkit to create windowed applications. I guess something like Visual Basic.


The bank switching seems to provide a similar thing though.


Somewhat isolated, yes. Not protected because there are no privileged instructions on a Z80.

Bank switching requires part of the address space to be common amongst all banks (never switchable) so code to manage the switching can execute. In that part of the address space you can do things like monkey patch the OS and driver entry points, or switch banks and collect or patch all the RAM.


Timer interrupt



Which is neither required nor sufficient for preemptive multitasking, which the OP was asking about. The 2nd set can speed up interrupt handling though (and was used this way in the BIOS/BASIC of Amstrad CPC).


I don’t understand. What would you need? You can look at the registers, save them, populate them with another tasks contents, rinse, repeat


Others have already correctly pointed out that you'll need a (periodic) interrupt source and facility to handle such. As the Z80 doesn't provide a protected or system mode, it needs to be a non-maskable interrupt, which the Z80 fortunately does provide (iirc, that wasn't used in the Amstrad computers though).

Sure you'll need to save the registers, but you could do that using the stack as well. The second register set just makes it quicker.


But if the processes don’t mask the timer interrupt, it could be used instead of NMI?


I’ve looked at a lot of the old architectures from the 1980s and gradually came to the conclusion that I liked the Z80 the best, particularly because it has a follow on

https://en.wikipedia.org/wiki/Zilog_eZ80

which has a 24 bit address space without the horrible compromises of this guy

https://en.wikipedia.org/wiki/WDC_65C816


Is this guy the WDC 65C816? Just want to know if I understood your comment correctly ir if I missed something.

Interesting that the eZ80 is used in the TI calculators. I wonder how energy efficient it is comparing to the ARM used in some HP calculators.


I would guess in terms of raw compute efficiency the ARM will beat the eZ80 due to the older Z80 architecture (3x faster than slow is still slow, and the HPs used ARM9 IIRC, while the eZ80 is more similar to an ARM7 and only a 24 bit ALU, etc). However for a hand held calculator it’s unlikely to make much difference where hardware process, power management/clock domains and peripherals are going to be much bigger issues.


Is there any point in buying a calculator anymore since you can write code even on your phone these days?


I think so, YMMV but the form-factor [1] of a calculator is beneficial. For example, if you are used to financial calculations on a HP 12C [2]. The calculator is small, is besides your keyboard, you just press a button (ON) to start it and a few keys combination for having a result, then turn it off. All while you, for example, are focusing on a document in your computer. Like a second or third monitor is complementary.

It is obvious that nowadays you can do the same in your computer but touching physical buttons makes also a different experience.

[1] https://magnetseven.substack.com/p/merging-craft-and-functio...

[2] https://news.ycombinator.com/item?id=38739673


Yes I did mean the WDC 65C816. It had a 24 bit physical address space but it didn't widen the registers enough that you could easily take advantage of it.


From a historical viewpoint I think that’s unfair to the 65C816. It was launched in 1985; the eZ80 in 2001.

That’s a long time to learn from other people’s mistakes, if they even were mistakes for the time. I can’t find numbers for either on the web but I guess that, being pipelined, the eZ80 uses more transistors than the 65C816 (also, a Z80 already has about twice the number of transistors as a 6502).

If that’s the case, a better ‘improved 6502’ might have been too expensive for its market in 1985.


You may be right. Zilog made numerous sequels to the Z80 in the 1980s that were somewhat going in that direction such as the Z180, Z280 and Z380 but none of them were as simple, clean and successful as the eZ80.

Being a little late the eZ80 benefits from a lot of insight, it makes me think if the AVR-8 which is another architecture which ‘completes’ the 8 bit age.


I was a 6502 guy back in the 80s, before I went 68k, and never had a machine with the Z80, so have no nostalgia for it. But when I look on paper, the Z80 really does look like it stood the test of time better.

How does the eZ80 extend out into 24 bits without having an awkward banking system like the '816? (EDIT: I see, it actually adds a 24-bit register mode.)

The biggest problem I found with the 816 was that having no registers larger than 16-bits meant, well, there's no way to store a pointer in a register, or work with data larger than 64k. Well, that and the awful 8/16 mode switching. Oh, and the fact that the stack and direct page are stuck in the first 64k bank. Damn, I really wish Mensch had designed and built a 65xx with a proper 16bit (or higher) architecture instead of the meh that is the 816.


They extended the length of the registers for the eZ80, which they didn’t do for the 816, it is explained really well here

http://www.zilog.com/docs/um0077.pdf

I made it through (most of) the 1980s with a 6809-based TRS-80 Color Computer but I think the 6502 was the most popular CPU in the US then, as the 6502 based PET, Apple ][, C64, Atari 400, Atari 2600 and NES used them. I think it was rare to see Z-80 computers with color graphics, framebuffers, sprites, etc. but it was used in arcade boards and they had this

https://en.wikipedia.org/wiki/MSX

in some other countries.

I wonder if you could build a OS for eZ80 that could run CP/M software, that would get you a pretty large base of software to run.

In an alternate timeline, Apple comes out with the iiGS a few years earlier than it did instead of the Mac but no the ‘816 was not that chip and they would have been looking for a replacement around the time they got looking for a 68k replacement.


When I started to look at the instruction set of the 816 more closely (and a coworker of mine was writing an emulator at the same time) it became clearer to me why Mensch went the route he did;

a) there just wasn't room in the 8-bit instruction encoding in the '02 to cleanly add 16-bit (or 24-bit etc) versions of each instruction. So instead of moving out into multibyte instructions, he introduced the mode switch and

b) he seems to have done this by doing very minimal surgery to the 6502 core itself, basically adding some 16-bit shunts (depending on mode) in front of the decoder to just change the register sizes and behaviors really. (apart from the improvements like adding relocatable direct page and movable stack, like the 6809 got)

c) apple wanted something that fit in a 40-pin DIP, to fit into existing motherboard design constraints presumably... and for it to support full 6502 compatibility. so we got this awful address bus multiplexing thing, and even after moving up into other packaging, he never fixed that (oddly he later made a microcontroller, the 65C265, that has all 24 pins without multiplexing). If he'd just started with PDIP-64 like the MC68000, so much agony would have been saved.

I think it's a shame really. We could have had a 16/24 version of the 6502 with fewer compromises if the 816 had been a more "serious" project from Apple. But at the time the IIgs was in progress and WDC commissioned to work on the chip, I suspect there was already the politics within Apple about killing the Woz-line in favour of the 68k Mac. We had IIgs systems in my primary school, and they only ever got used as Apple II clones.

I had an Atari ST, and while the 68000 was a great chip, it was clearly targeted towards "VAX" class or workstation type applications originally. Its overall complexity is quite high, and interrupt responsiveness very slow, when compared to the 6502. It would have been interesting to see a Mensch-designed 16/[24/32]-bit processor that kept the same minimalist philosophy as the 6502. Paired with a chipset like what was in the Amiga, I think it would been really cool.

Though maybe the ARM line is that, in some ways.


I looked it up and the eZ80 is instruction set compatible with Z80 so I think it could run old CP/M binaries. You would have to customize the BIOS to add support any IO devices.


I'd imagine the ez80 uses an extended register fusion setup ie. You can use 3 8bit registers as a 24bit register. I think that would take 3 cycles to use the full address space, but for the first 8bit space I guess it would work like utf8 in that you just use 1 register (byte).


Back in the day I bought a TRS-80 instead of an Apple ][ based on how much easier the Z-80 looked to write assembly for.


I believe this is the CPU used in the Agon series of retro / hobbyist single board computers.


Yep

https://www.olimex.com/Products/Retro-Computers/AgonLight2/o...

for a while I thought this was pretty cool

https://www.commanderx16.com/

but then I saw the Agon stuff which I think is miles better not to mention more affordable.


I recently played around with this at MSXGOTO40. Crazy to see an MSX do all of this. Videos at https://www.youtube.com/@Prodatron


Notable videos:

lymings (lemmings) with sound https://www.youtube.com/watch?v=PfkJLP45FWk

multitasking with pacman https://www.youtube.com/watch?v=Ish4ReOjdIw

networking with wget and IRC https://www.youtube.com/watch?v=bB6X7V6fVyE


Thanks, that gave a good impression of SymbOS which is boggling my mind a bit.


Yeah, I was totally flabbergasted.. Seeing an old rusty MSX of almost 40 years old pulling off multitasking. They had quite a few apps and games (even the z80 doom haha).

I talked to one of the members for a while.

So basically they use none of the BIOS, so it's purely Z80, which makes it super portable.

They do have different drivers for different videocards. So some configurations work faster than others. I saw a stock MSX and one with some videocard, but I can't remember exactly. The stock one was slow with redrawing at times, but the other one was very smooth.


I was very regretful that my first (Nascom 2) didn’t leverage interrupts more. I hated that loading/saving to tape were simultaneously insanely slow and blocking operations. The slowness would have been easier to stomach if I could do something else while waiting. It wasn’t a technical problem. I had seen concurrent CP/M in action and that was amazing.


Amstrad CPC! I can remember when you could buy one at the department store. Computing was adventurous exploration then.


The thing I miss the most is every device having an answer for “what makes this thing interesting or unique”. No longer is that true or as relevant really.


Two friends and I started an impromptu coding session last night on my first Amstrad CPC464 bought in 1988. It turned out to be my name sinusoidally moving over the screen. It was so fun to discover BASIC commands and implement effects together. Only photos of the event left though because there was no tape to save the work :)


My dad got me a Amstrad system here in the US when I was a teenager. It was sold as a word processer system with a high resolution green monitor and a nice printer. But it was not of use for anything else due to the nonstandard floppy form factor. And any games I could get would have to come form the UK so very expensive and hard to get. It did have CP/M, BASIC and Logo so I also learned about that.

The biggest use out of that system was once I typed up an Eliza chatbot BASIC program from a library book. Its quite simplistic but turned out very entertaining to young children like our close neighbors young kids and much later my young nephew/niece. They would always ask for the "Green monitor" anytime they visited and spend hours on it. Much later when we meet up they still recall that "Green monitor" they had fond memories of.


That was probably an Amstrad PCW series computer. Never used one, but heard a lot about them. The machines of the era were very remarkable that they made the most of its users write programs, something we see rarely these days.


Yes I looked it up and it was one of those Amstrad PCW computers.


> Preemptive multitasking - 1024 Kb dynamic memory - 2 terabyte filesystem

For those occasions you need 2TB attached to a z80...


2TB is a familiar limit (MBR).

512 byte blocks addressed by 32bit block number.


When I see this type of marvels I stare at my mobile phone and think about the amount of wasted power. Such powerful hardware should be able to let me do a lot of things and instead it doesn't.


Battery life. Compute has overshot battery life.


In line with that, it’s crazy to think how portable 8-bits could once be powered off standard AA batteries…


Oh, even 32-bit machines (the pre-ARM Palm PDAs in the 1990s which used the 32-bit Dragonball processor) used standard alkaline batteries (3 AAAs)


Maybe not 8-bit, but my HP 200LX runs months on 2 AAs and is only moderately bulkier (thicker) than a modern smartphone. With a CF card you can have hundreds of excellent DOS programs/games on it.


99% of compute power is wasted. You just know a 1GHz Z80 mobile phone with SymbOS would be smooth as silk...


Is it battery life and thermals?


Maximum power dissipation 0.79 Watt


That too!


Don't get me started on game consoles....




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: