I wish I'd had this book back in high school. Then again, I might not have appreciated it much back then, or I might have scorned my Z80 past as I don't today.
The first half is all (assembly language and machine code) software, and the second half is hardware interfacing for which a bit of grounding in digital logic (which I've picked up only ad-hoc) is required. But I've never really wanted to play with a breadboard before, and second half of this book had me wanting to do that.
(Another problem is that I don't even know how you're supposed to play with real serial and parallel ports anymore.)
Contents:
Chapter 1. Introduction to Microprocessors. Chapter 2. Z80 Architecture. Chapter 3. Data Transfer Instructions. Chapter 4. Arithmetic and Logic Instructions. Chapter 5. Program Control Instructions. Chapter 6. Assembly Language. Chapter 7. Structured Assembly Language Programming. Chapter 8. Data Manipulation and Arithmetic Programming Techniques. Chapter 9. Conversions, Table Lookup, and Time Delays. Chapter 10. Introduction to the Z80 System Architecture. Chapter 11. Memory Interface. Chapter 12. Input/Output Interfacing Using Parallel Ports. Chapter 13. Serial Communications. Chapter 14. The 8254 Programmable Timer. Chapter 15. Analog-to-Digital and Digital-to-Analog Conversions. Chapter 16. Introduction to Advanced Microprocessors. (meaning: the 8086 and 68000, with the briefest of mentions given to the 80386 and 68020)
Anyway, this was much more fun than a 22-year old textbook deserves to be. While I was reading this I poked my head into the instruction set of the Java virtual machine for the first time, and it's eye-opening to contrast the differences in approach between that stack-oriented machine and the heavily non-orthogonal Z80. (Actually, the JVM isn't perfectly orthogonal, either--the designers gave that up to fit the number of opcodes within one byte.)
I really should try to get to Knuth's MMIX book so I can seriously grapple with RISC.