4 ms·
The New ROM Antics – Building the ZX Spectrum 128
- hnthrowaway0328 3y agoSystem programming: the only viable option for hackers who prefer machines over humans. Thanks for sharing.
- gede171 3y ago[flagged]
- gede171 3y ago[flagged]
- gede171 3y ago[flagged]
- gede171 3y ago[flagged]
- klelatti 3y ago> I stole copiously from The Complete Spectrum ROM Disassembly by Ian Logan and Frank O’Hara This was an actual book, readily available at your local bookstore, that had a full, independently produced, Z80 disassembly listing (with great comments) of the original Spectrum's 16K ROM. That the actual Sinclair team were using it as their main reference when they updated the ROM is just fantastic.
- timthorn 3y ago> This was an actual book, readily available at your local bookstore Or on my bookshelf, still :)
- klelatti 3y agoSame here! For those not similarly blessed, the Internet archive has a copy. https://archive.org/details/CompleteSpectrumROMDisassemblyThe https://archive.org/details/CompleteSpectrumROMDisassemblyTh... Of particular note, the use of a stack based VM for floating point.
- timthorn 3y agoI will presume that you know of the more recent tome on the ULA? "The ZX Spectrum Ula: How to Design a Microcomputer" by Chris Smith
- nickt 3y agoDitto. If you’re a Sinclair fan, all his books are worth a read. http://www.ianlogan.co.uk/sinclair/books.htm http://www.ianlogan.co.uk/sinclair/books.htm
- helpfulContrib 3y ago[dead]
- PreInternet01 3y agoFor those curious about what the original Spectrum ROM looked like: https://skoolkit.ca/disassemblies/rom/maps/all.html https://skoolkit.ca/disassemblies/rom/maps/all.html (The tool used to generate this, https://github.com/skoolkid/skoolkit https://github.com/skoolkid/skoolkit, is absolutely amazing and still sees regular updates)
- peterfirefly 3y agoThere is a link at the bottom to switch addresses to hexadecimal.
- varjag 3y agoThe listing appears to be a copy of Logan's book, down to the labels and comments. EDIT: it does say so in the footer.
- peterfirefly 3y agoThank you so much for this link -- I have finally satisfied my curiosity after 40 years! I've spent some time today looking into the floating-point routines. Some parts are quite nice, others are a bit... clumsy. Something that surprised me was that they use 5 constants (0, 1, 0.5, pi/2, 10 -- in that order) stored in some sort of ad hoc packed format. That saves all of 7 bytes but the code to handle that takes more. Why?! There is a routine that takes a constant index (0-4) in the A register and stores the (unpacked) floating-point constant on the calculator stack. It does that by skipping the constants before the desired one -- and that is done by performing a dummy unpack on them (by unpacking them to a ROM address). See: https://skoolkit.ca/disassemblies/rom/hex/asm/341B.html https://skoolkit.ca/disassemblies/rom/hex/asm/341B.html [ah, the mystery is solved later -- see below] There are low-level routines for addition, multiplication, division, abs/neg (they share most of their code), and some low-level stack manipulation. There are special-cased comparison operations for 0 and true. OR and AND build on those special-cased comparison operations. Subtraction is built on neg + addition. sin/cos/tan/arcsin/arccos/arctan/exp/ln perform argument validity checking, argument reduction, and then evaluate a Chebyshev polynomial (and clean up the result). There is a special "series evaluator" function for that + some of the routines share their argument reduction code. The power operator is built on ln and exp. The square root operator is built on the power operator (x^0.5). Most of the internal floating-point code use a compact VM to represent calculations involving other, lower-level floating-point code. We enter the VM with the RST $28 instruction (a single-byte call to address 28h) and then a stream of single-byte opcodes follow, with the last one being a terminator. Each opcode encodes a call to a single floating-point operation. Some have immediate bytes: the opcode for pushing (packed) immediates to the calculator stack, the opcode for invoking the Chebyshev series evaluator (it is followed by a number of packed constants), and the opcodes for a loops and branches (followed by a single displacement byte for two of them). The loop instruction is basically a DJNZ, the unconditional branch is a "JR", and the conditional branch is a "JR true" where "true" is taken to be a non-zero value at the top of the calculator stack (it doesn't get popped). So, it turns out that all floating-point constants in the ROM are in the packed format. That solves the mystery above. The Spectrum uses a 5-byte floating-point format with a full byte for the exponent -- this is much easier to work with on a Z80 than the 32-bit IEEE format (because the Z80 is really not good at bit fiddling across bytes). It also encodes a 16-bit integer format into the same 5 bytes, which speeds up most parts of a typical BASIC program (+ avoids weird rounding errors). The floating-point package handles both formats -- the outermost routines "unpack" the integers to real floating-point if necessary, the innermost routines only work on real floating-point numbers. --- There seems to be a bug in the comments for the LN function: https://skoolkit.ca/disassemblies/rom/hex/asm/3713.html https://skoolkit.ca/disassemblies/rom/hex/asm/3713.html It says: 3717 DEFB $00 jump_true to VALID: X 3718 DEFB $04 multiply: X It should have said: 3717 DEFB $00 jump_true to VALID: X 3718 DEFB $04 because the 4 is not a multiply opcode, it is just the displacement immediate for the jump_true opcode. --- Most VM opcodes are treated simple enough: just use the opcode as in index into a jump table. If bit 7 is set, we have a special case: The real opcode is in bits 6-5 and there is a parameter encoded in bits 4-0. This is used for the opcodes that push a known constant (0, 1, 0.5, pi/2, 10) to the stack, it is used for the series evaluator, and for pushing and popping any of 6 internal floating-point "registers" (used for FOR-NEXT loops and various other routines). The series evaluator uses the parameter in the low nibble to indicate how many constants to use: 6, 8, or 12.
- neilv 3y ago> The rush job was the UK launch of the ZX Spectrum 128, now known as the Toast Rack because of the lake heatsink bolted on the side. https://en.wikipedia.org/wiki/File:ZX_Spectrum128K.jpg https://en.wikipedia.org/wiki/File:ZX_Spectrum128K.jpg The heat sink fins really add to the aesthetic, and that looks so cool for a small home computer in 1985, who could complain. (The black NeXT cube wasn't for another few years, and it also cost a prohibitive sum for most homes.)
- nottorp 3y agoOh, the days a computer could get away with just a heatsink instead of 20 fans...
- bewilderbeast 3y agoThe heatsink cools the LM7805 power regulator, not the CPU. In the original 48k Spectrum, the heatsink was internal.
- nickt 3y agoAnd if you use a modern switch-mode replacement, you don’t need a heat sink at all. I know some folks like to put small heat sinks on the ULA though.
- SomeoneFromCA 3y agoSoviet clones had ULAs built from individual 74xx ics. No need for heatsinks!
- nickt 3y agoExcellent! I need to mess around with them at some point.
- egypturnash 3y agolooks at the Macbook Air she's typing this on now