Z80, the 8-bit Number Cruncher (2011)
andreadrian.de
andreadrian.de
Back in the day I wrote 10s of thousands of lines of Z80 assembler - it was my first actual paid job after university.
You got to know each register - they have their own character - need a loop - well you need B and DJNZ, need programmable IO, well you need C then, etc
I still have a soft spot for the Z80!
Reading that article I learnt some great techniques! The code I was writing always used the alternate register bank for interrupt handling so you could have really fast save and restore registers.
I never thought of using them to pass parameters and doing fast arithmetic - very neat!
; ADD ROUTINE 32+32BIT=32BIT
; H'L'HL = H'L'HL + D'E'DE
; CHANGES FLAGS
;
ADD32:
ADD HL,DE ; 16-BIT ADD OF HL AND DE
EXX
ADC HL,DE ; 16-BIT ADD OF HL AND DE WITH CARRY
EXX
RET[1] http://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-h...
EDIT: Just to be clear this is in no way intended to be a criticism of the Z80. On the contrary it's a tribute to the ingenuity of Federico Faggin and Masatoshi Shima that they were looking for ways to 'save' transistors in the ALU in a way which no-one would notice, which presumably enabled them to add more features elsewhere.
But the 4-bit ALU was the result of a very astute observation that inefficiencies in the 8080 microachitecture would hide an extra ALU cycle.
What (wiki?)books can I purchase that would help me bridge my mental understanding of computer circuitry from 'this is a circuit with a resistor and a power source and a lightbulb, while this is a CPU that has wires to memory and magic happens to make em talk' to 'I know the difference between TTL logic and a microprocessor and can fuzzily trace where the electrical signals go'?
I don't own but am aware of things called logic analyzers, 'progammers', and the difference between a microcontroler and a microprocessor (ish, the former is vaguely a system on a chip?), but I'm not sure where to start to fill in the many gaps in the bits of knowledge I have so far.
Wikipedia feeds me articles about logic gates, programmable logic, and Algorithmic Logical Units used in things like the Xerox Alto, but I don't know if this means I should try for electrical engineering courses or something simpler?
[1] https://www.youtube.com/watch?v=HyznrdDSSGM&list=PLowKtXNTBy...
What a helpful online community.
It's what made things click for me.
[EDIT: I also second Klelatti's suggestion... Ben Eater's youtube channel is ALL gold. He's an amazing teacher. I also purchased his clock module, and the 6502 kit - they are awesome!]
I think the missing link you're looking for is the flip-flop [0]. It's a clever arrangement of logic gates (just AND, OR, NOT, etc) that can store a bit. The concept of a clock signal is very closely related. Then you learn about multiplexers and you realize that if you put a bunch of flip-flops that can store a bit behind a multiplexer [1], suddenly you have something that looks like very primitive RAM with a data and address bus!
At the time it blew my mind that you can (conceptually, at least) take a bunch of logic gates, arrange them in clever ways, and arrive pretty quickly at much "higher level" concepts like memory on an address bus.
[0] https://en.wikipedia.org/wiki/Flip-flop_(electronics)#D_flip...
[1] https://en.wikipedia.org/wiki/Multiplexer#Digital_multiplexe...
The general progression is:
1. Circuit Theory (how fundamental components work)
2. Semiconductors(diodes, transistors, op-amps [skip those for now])
3. Digital Electronics (basic logic gates and boolean algebra)
Once you finish learning about digital electronics you should have the fundamental knowledge to understand how a basic processor might operate. A reasonably good place to start might be here.https://www.allaboutcircuits.com/textbook/
Read Volume 1, Volume 3 (skip chapters 7-13), and Volume 4. That should get you up to speed reasonably quickly.
Code by Charles Petzold, The Elements of Computing (Nand2Tetris course book), No Starch Press's Secret Life of Programs, Learning Computer Architecture with Raspberry Pi
It was perfect for such applications!
Good memories.
http://dataprobe.com/iboot-hub/
It had a built-in web server running on an 8051! It interfaced with an Ethernet chip using a parallel FIFO interface- maybe NE2000 based chip? I don't remember..
PMESS LD A,(HL) ; get character from message
INC HL ; move message pointer to next character
CP 10 ; newline?
RET Z ; return if so
OR A ; zero?
RET Z ; done if so
CALL PCHAR ; print character
JP PMESS ; keep looping
If instead of "RET Z" we had to do a conditional jump to a return it would be 10 cycles for each test instead of 5. CP 10
JP Z,DONE ; 10 cycles, jump taken or not
...
JP PMESS
DONE: RET ; 10 cycles, BTW
The conditional return just happens to be cheaper if not taken because it skips the work of popping the return address off the stack. Though purely an outcome of the implementation you can treat it as sort of a branch prediction.Incidentally, the Z-80 also has relative branches (JR) that differ in execution time whether they are taken or not. The branch offset is a single byte so JR is only 2 bytes compared to JP's 3. A JR is 7 cycles if not taken, 12 otherwise. Again, we can treat it as a hard-coded branch prediction that predicts the branch is not taken. If space or distance to target is not a problem, a JR is faster if taken less than 60% of the time.
Absolute jumps ("JP") were 3 bytes, relative jumps ("JR") were two, whether conditional or not -- but, that's still longer than the 1-byte return instruction...; Though, absolute jumps were the fastest - they did not need to access the stack and adjust SP like "ret", and did not need to do addition like "jr".
I used to know the opcodes by heart, but I last wrote Z80 code in 1987, and last wrote x86 machine code in 1997, and nowadays I don't remember all of the binary representations, and sometimes I get the binary representations of the two mixed. I'm getting old ...
The 6502 has only an 8 bit stack pointer which points into page 1 only (addresses 0x100 .. 0x1FF).
I can hardly imagine how different things must be now for young kids growing up in internet era, where everything is at your fingertips. Information was much more difficult to get back in the old days, traveled much more slowly. But, still, kids had the energy to figure things out.
Z80A $6.00
Z80B $18.95
6502 $6.95
6502A $12.95
6809 $24.95
8088 $39.95It came a few years later but the ARM1 which used 25,000 transistors and was built on roughly the same process size [1] and was much faster than the 8086/8088 shows what might have been had Intel gone down a RISC route.
[1] https://en.wikichip.org/wiki/acorn/microarchitectures/arm1
The 8086 the 8088 was based on was released in 1978. The ARM1 was released in 1985. That was an eternity.
As has been said elsewhere the ARM1 wouldn't have worked commercially in 1978 because of code density and bus width.
I do think though that if you look back at the history Intel put huge resources into the iAPX432 which was hugely overambitious and they had to rely on the fallback of the 8086/88. There is probably a reasonable case that if they had hadn't split their resources we might have had something better than the 8086.
Edit: By complete coincidence browsing some related Z80 came across your memcpy comparison which is fascinating. The step up to the ARM1 is remarkable. I think I remember Herman Hauser saying that Acorn approached Intel for an x86 chip with higher memory bandwidth but were rebuffed and that led to the development of Arm.
She is in a position to know.
Incidentally, Robin Saxby the first CEO of Arm previously worked for Motorola and tried to sell the 68000 to the Acorn team!
Indeed the Z80 was used in the Amstrad CPC series. There, the firmware used the alternate register set for bookkeeping, so you could use them only in a code region surrounded with interrupt dis/enabling and saving/restoring them. The floating point format on the CPC is 40 bits, probably one of the formats mentioned in the article.
A few people still create prod for the Z80 every year, there are already 10 productions registered in 2020 on http://www.pouet.net/prodlist.php?platform%5B%5D=Amstrad+CPC...
The CPC had a huge graphics memory for the time: 16k, making nice-looking games in paper catalog but very limited full-screen animation without piles of hacks.
Lots of actual number crunching for 3D graphics in thi old prod "All in 3D" https://www.pouet.net/prod.php?which=14667 (no video, you have to run it e.g. in an emulatoe).
For an exceptional result of Z80 performing number crunching and graphical hacks, see this nice demo from 2017 "Amstrad CPC demo : Logon's run - 3D meets the aging bits" https://www.youtube.com/watch?v=22wSm4y27Wk . Or "Batman Forever" demo of 2011 https://www.youtube.com/watch?v=_syHewDu5lc
I personally made a production this year https://gourichon.org/cpcitor/justget9/beta/ a puzzle game with smooth animation, which got awarded at a local contest https://www.facebook.com/groups/1120607071477318/permalink/1...
See this document about the carry and overflow flags: http://teaching.idallen.com/dat2343/11w/notes/040_overflow.t...
The code for comparing HL >= DE should be: (Replaced JP PO by JP M + inversion of the sign if overflow)
;==================================================
; IF-ELSE CODE FRAGMENT
;
LD HL,-2000 ; HL = -2000;
LD DE,-1000 ; DE = -1000;
AND A ; if (HL >= DE) {
SBC HL,DE
JP PO,NOOV
LD A,H ; INVERSE SIGN BIT IF OVERFLOW
XOR 80H ;
NOOV:
JP M,ELSE
LD A,1 ; A = 1;
JR ENDIF
ELSE: ; } else {
LD A,0 ; A = 0;
ENDIF: ; }
HALT
ENDThing is, since I am a game-dev: it would be cool to have a cheap console or portable console that runs at quite high speeds.
For example what would be possible if I had a Z80 that ran at 2ghz?
Z80 machines of the 8-bit era were typically 2MHz or 4MHz.
Toasted Z80