Yes, I found the eZ80 rather nice - thereās one in the Agon Light 2, and possibly in other modern retrocomputers.
I particularly like the way the backward compatible Z80 mode is handled - itās much nicer and more flexible than the nearest idea in 6502 land, which is the 65816.
In fact I drafted some notes in April last yearā¦ let me copy/paste from thereā¦ this might be mildly incoherent. I notice that I make a very different statement there about the reasons for the relative performance improvement:
ā¦very recently I bought a new modern retrocomputer, the Agon Light, which uses an eZ80 and adds 512k of RAM (and also has an ESP32 for graphics, sound, keyboard.) By default the Agon boots to BBC Basic for the Z80, and uses something rather like Acornās bytestream VDU protocol for graphics. The BBC Basic is I think closely derived from Richard Russellās Z80 BBC Basic from the 1980s, and as usual it includes an assembler.
So, I have a modern fast Z80 and Iāve been reading up on it. It seems to me that Zilog have done a very good job of making a compatible 16/24 bit extension to an 8/16 bit original. ā¦ Itās quite a different approach from the '816.
Before looking into how itās done, letās see what we get:
- an 8 bit wide memory system, with 24 bits of address.
- a very compatible z80 mode, running in a 64k space.
- several z80 applications can co-exist, isolated from one another, each in their own 64k section of the 24 bit space.
- an extended mode (ADL mode), where all the 16 bit registers are 24 bits, and all instructions act accordingly, in a flat 24 bit address space.
- a mixed mode which allows interrupts to run in the extended mode and return to a z80 application or to an extended mode application. It also allows extended routines to call Z80 routines, and vice versa.
- a means for individual instructions to operate in a chosen mode, overriding the current mode
It seems to me to be very attractive.
Letās look at some of the technicalities of the ez80 implementation:
-
instructions are, as before, variable length in bytes, and most take one clock cycle per memory access, running in a pipeline to hide some of the cost.
-
thereās a single byte-sized register to supply the top 8 bits of 24 addresses when z80 mode supplies a 16 bit address. Itās called MBASE, and the z80 mode canāt see or modify it.
-
the z80 mode canāt see or modify MBASE (this is safety and simplicity, not security!)
-
all the instruction encodings are the same, the action depending on the mode and/or the use of a single-shot prefix
-
just a handful of extra opcodes are needed, and theyāve taken four NOPs from the z80 encoding for the purpose.
-
there are two mode bits, one to set extended addressing, and one to select mixed-mode operation
-
the high and low bytes of 16 bit registers are individually accessible as is usual for z80
-
in extended mode, itās the middle and low bytes which are individually accessible: the high byte is involved whenever the whole 24 bit register is accessed.
-
the stack pointer is handled specially: thereās a 16 bit stack pointer for z80 mode, and a separate 24 bit stack pointer for extended mode. The mixed mode deals with interrupts by using the 24 bit stack and pushing a mode byte so it can return to the caller appropriately. The ISRs themselves run in extended mode.
Notice that thereās no wide memory or wide instruction decoding.
Note that the z80 has advantages in having many 16 bit registers including a 16 bit stack pointer: extending them to 24 bits while the 8 bit accumulator and register-halves remain at 8 bits seems quite natural. The trick of having a separate extended mode stack is simple and effective in allowing for mixed-mode interrupts. Somehow the mixed mode calls and returns work out too: I havenāt quite fully understood the call and return process as yet.
Postscript to my observations, made a little later:
I see a zilog doc specifically about the modes and mixed-mode operation which might help me understand more about that. Only 18 pages too.
http://www.zilog.com/docs/appnotes/an0339.pdf
(already, I see they say that the āfour times fasterā that they bandy about is not about the simpler clocking or the single cycle instructions, itās about the improved efficiency when running in ADL mode. In other words, itās approximate and code-dependent.)
Perhaps a good starting point for me would be to ask why we need the mixed-mode bit at all. We donāt need it for ordinary coding purposes, where code stays in one mode or the other. But, here it is: if we call an other-mode subroutine, we need it to stay in other-mode throughout, until the return, where we need it to revert to the calling mode. Clearly enough, this is a stackable kind of thing, because the call stack could be deep and keep switching modes. And we canāt stack this callee-mode-signifier on the 8-bit stack because thereās not much room there and code wonāt be expecting it. So, for cross-calls and for interrupts, we need to stack the current mode and later restore it.
Having said all that, I still havenāt yet seen the need for a mixed-mode bit.
I realise thereās probably a bit of a gap in my understanding so Iām going to go back to the PDF.
The ez80 as a whole has an ADL mode bit and a MADL mode bit. But the four new prefixes temporarily set modes SIS, SIL, LIS, LIL, and I havenāt fully understood how they affect what happens. I think SIS and LIL represent the z80 mode and the ADL mode, but the other two are a bit mixedā¦ not quite sure that thatās the same as the MADL bit. It ought to beā¦
I suspect the split stack isnāt an issue: you could almost think of it as a user mode stack for the z80 application and a supervisor mode stack for the ISRs. What you canāt do is run your ISRs in Z80 mode, I think, unless you have MADL=0 and are running pretty much as a Z80. Which you could do - the extra RAM would be accessible using prefixed instructions, but you probably wouldnāt run code outside the 64k you were in. But the more sophisticated thing to do is have your supervisor/MOS/ISRs in ADL mode, and your applications in either z80 mode for backward compatibility or in ADL mode for a big flat memory model.
ADL mode has a built in performance penalty because of the larger operands, but maybe gains a bit from the wider operations. As the accumulator remains 8 bit, you donāt get the wide machine you might hope for. And your previously 16 bit registers are now 24 bit, so you canāt easily do 16 bit or 32 bit datatypes. 48 bit long ints, anyone?
Hereās a diagram from the datasheet: