This month SIMON N GOODWIN delves into the +3 ROM and disk system, reveals secret machine-code instructions, and reports on the CRASH Tech Tape and MGT’s SAM.
In the meantime I’ve spent a while looking at ZipZap, a +3 disk utility that should appeal to hackers and regular disk users.
ZipZap, from Omega Software, is a disk sector editor — a program that lets you read and edit the raw information recorded on a +3 disk. This is useful if you want to edit programs or header information without loading files into memory — perhaps to change the starting line number on a BASIC file, or to patch text or code.
ZipZap can be even more useful if something goes wrong with a disk — should you erase a file accidentally, or a mechanical fault wipes out part of a file, for instance. In the first case, as long as you have not written anything new to the disk you can retrieve the data by just changing a few characters in the index or ‘directory’ the disk uses to keep track of files.
In the second case you’ve probably lost the data that’s on the physically damaged part of the disk, but you can usually retrieve most of the file by changing the directory entry so that the computer skips over the damaged part.
ZipZap can read any part of any disk produced by +3 DOS. It doesn’t load or save files in the usual way, but instead works with the individual lumps of information on the disk, known as sectors.
The data on a +3 disk is spread over 40 rings, or ‘tracks’, each a fraction of a millimetre wide. The disk head — the part that reads and writes data — steps back and forth from track to track, so that any ring on the disk can be accessed.
Each track is divided up into nine sectors, each of 512 characters, and sectors are allocated in pairs to each file. As files grow they are allocated new sectors, and a ‘directory’ is written on the outside of the disk to keep track of which sectors belong to each file.
There’s no necessary connection between the order of sectors on the disk and their apparent order when you load a file, although it’s rare for a file to be scattered all over a disk — the Amstrad software, +3 DOS, just doles out sectors from the unused ones as required, and re-uses sectors when a file has been deleted and its space is needed.
The system reads a particular sector by moving to the appropriate track and reading the sector numbers, recorded before each lump of data, until it finds the sector it wants. The disk turns at 300 RPM, so there’s not usually long to wait.
ZipZap lets you drive the disk head around and grab sectors by number or at random as they come off a particular track. You can then print, display, edit or replace the sector. Standard disks use sector numbers from 0 to 8, but ‘protected’ disks tend to use higher numbers that can only be read with special software.
Other protection schemes use a mixture of single and double-density recording. ZipZap can read and write these, although it takes a fair amount of fiddling around to write single-density tracks.
You can read most types of protected disk with ZipZap, but the utility relies on the +3 DOS ROM routines, so it can’t read all recordings generated by programs that manipulate the disk controller directly. ZipZap itself was protected when it was launched, but I’ve since persuaded Omega Software to remove the protection.
At the moment, commercial programs use +3 DOS routines because direct control is a fiddly and error-prone business. It’s fair to assume that ZipZap will read the vast majority of +3 disks, including anything you format yourself, but it’s not guaranteed to read absolutely everything.
ZipZap uses a fixed display format. The top part of the screen shows the current quarter sector, with 128 bytes of data arranged in two sections. The left side shows hexadecimal data values, and the right side shows text.
You can edit either part by moving a cursor over the data. There’s no shortage of commands to move around the screen, memory or disk surface — you’ll probably end up using just a subset of the available commands.
The lower third of the screen shows the current drive, track, sector, memory address and cursor position. It’s also the place where messages appear.
ZipZap is controlled with single keys, sometimes used in conjuction with Symbol shift. The ‘Z’ key gives a three page list of the 49 controls, with single-line explanations of their effects.
Numeric values must be entered in hex — base 16. Most machine code programmers will be happy with hex input — personally, I hate it — but the rest of us just have to get used to 1F being one less than 20, or 32 as we know it in decimal! ZipZap includes a command to convert hex values to decimal, but not vice versa.
Hex makes for a neat display, as every value can be written in two ‘digits’, 00–FF, rather than three (000–255) in decimal, so perhaps it’s worth the hassle. Nonetheless, the Spectrum cannot display enough standard-sized characters to show a complete sector on the screen at one time, so each sector is shown in four quarters, with a code letter A to D to identify each part.
ZipZap can read and write sectors into a ‘buffer’ of 512 bytes of memory. The top 32K of RAM is reserved for 64 of these buffers, so you can build up files in RAM and edit them with POKEs from BASIC, if that’s what turns you on — you can leave ZipZap at any time without losing data, although there’s only about 2K left for ZX BASIC.
You can change buffers by pressing ‘B’ followed by the buffer number in hex, or just use ‘E’ to Exchange between an odd and even numbered sector — convenient when editing one buffer and keeping the directory in another. Buffer contents can be edited just like disk sectors.
The ‘P’ key sends the sector on the screen to a serial or Centronics printer, using a double-width format to save paper.
Key ‘S’ controls a useful search option which scans the disk or memory for a given sequence of up to six characters. Unfortunately you have to enter these by character code, in hex. Searches in RAM are very fast, but disk access is slowed by +3 DOS. It takes about three minutes to search through an entire 180K disk, but you can stop the search at any time by pressing BREAK.
ZipZap costs £12.95 on 3 inch disk, with an A4 manual and a ‘bonus’ in the shape of a rudimentary but useful utility program: SuperCat lets you check the exact size and SAVE parameters of files, rather like the tape command CAT "T:".
The ZipZap documentation is well written as far as it goes, but that’s not really as far as I would like. It’s heavy going for a beginner, as it assumes you’ve read and understood most of the disk information in the +3 DOS manual, but it contains enough examples to get you started.
The program is fairly easy to use once you’ve worked out how to read the directory and track files down on the disk, but it works more like a hexadecimal spreadsheet than a friendly, menu-driven utility. The first version I was sent for review reported errors by number, but the latest one prints full messages, using the normal Amstrad text.
ZipZap is a very useful tool, but it takes a while to get used to it unless you’ve used a disk sector editor before. You may find using it an uphill struggle if you’re easily phased by screenfuls of numbers, but it’s worth persevering.
Over the years I’ve had several letters from readers asking about the ‘undocumented’ instructions rumoured to be recognised by the Z80 processor in all models of the Spectrum.
Microprocessors work by reading numbers from memory and performing different actions depending upon the exact values, known as ‘op-codes’, which they find. ‘Op’ is short for ‘operation’. Each code causes the chip to perform a distinct operation on values in memory or inside the processor.
According to Zilog, the firm that first made the Z80, the Spectrum processor can recognise 696 different op-codes. After some research I’ve identified about a hundred extra operations that the processor will recognise, but which Zilog chose to keep secret!
There are various possible explanations for the secrecy. Some of the ‘new’ instructions are not very useful. Others conflict with the way Zilog expected the Z80 to be used — they work fine, but make the processor even more fiddly to program than it normally is. A few op-codes appear to work by accident — they’re recognised by all genuine Z80 processors, but they only work as side-effect of other instructions.
To understand more you need to do some detective work, and examine the actual instruction code. At this point I’m afraid have to wave goodbye to anyone who does not already have a reasonable knowledge of machine-code — it would take most of this issue of CRASH to explain this from first principles. If you want to learn about machine code, try Toni Baker’s book Mastering Machine Code on the ZX Spectrum, published by Interface.
The Z80 instruction set is a souped-up version of the set recognised by the Intel 8080, one of the earliest useful microprocessors. The 8080 recognised 250 instructions, as it used most of the possible values for a single-byte op-code.
Zilog designers left Intel and added hundreds of extra instructions by making special use of the unused 8080 op-code 203 — CB in hexadecimal. This code was declared to be a marker, indicating that the next byte was the op-code of a special Z80 instruction.
The new instructions required two bytes of op-code, unlike the 8080 instructions which could get by with one byte. All the short 8080 instructions still worked, and Zilog got lots of extra op-codes to play with, at the cost of longer, slower instructions.
In theory this trick should have given Zilog an extra 256 op-codes. In fact, when you look through the list of instructions and character codes printed in all Spectrum manuals apart from the trashy Spectrum+ booklet, you’ll see a curious gap in the second column of instructions.
According to the manual, you get a valid Z80 instruction if you follow a 203 byte with any value EXCEPT a byte in the range from 48 to 55. There’s no hint of what happens it you use these eight combinations.
When you examine the other instructions listed you soon notice that they’re arranged in groups of eight. Each group of instructions works similarly, but individual instructions in each group affect different registers. The first in each group handles register B, then C, D, E, H, L, (HL) and finally A. So it’s a good bet that the missing codes follow the same pattern.
Before the missing instructions come various op-codes that shift binary values sideways. There’s an arithmetic shift left, then an arithmetic shift right, then the gap, followed by a logical shift right. It seems very likely that the missing instructions were meant to perform a logical shift left.
When you try it, you discover that the instructions DO shift binary values to the left, in the registers you’d expect. But the rightmost bit is always SET after the shift, whereas you’d expect a logical shift to leave it clear. This is not the conventional result, and presumably that’s why Zilog those to keep the instructions secret.
Now that you know what the instructions do, you can use them in your own programs. They have the effect of doubling the value in a particular register and adding one to the answer. It’s unlikely that you’ll often find this useful, except perhaps in serial data-handling routines, but at least now you know that you can do it!
There are a couple more instructions in the same vein. Zilog use two more marker values, 221 and 253, to indicate that the following instruction, which would normally use the HL register pair, should use the new Z80 registers IX or IY instead.
Zilog markers sometimes work in combination, so if you put the sequence of bytes: 221, 203, 54 in your program you can Shift Left Logical the byte pointed to by IX. This is an indexed operation, so a single byte offset from IX should come at the end of the instruction, after the 54.
The offset is stored just as in the instruction LD B,(IY+34), which uses 70, the code for LD B,(HL). with a 253 in front to select IY, and the offset 34 at the end, making the whole instruction: 253, 70, 34.
Now you know about the markers for IX and IY, another idea may cross your mind, If these values tell the processor to use IX or IY instead of HL. what do they do if you put them in front of the 8080 instructions which don’t use HL?
Before the Spectrum was invented I used to write for a magazine called Computing Today, now defunct, One of the contributors, D S Peckett, discovered that the 221 and 253 markers for IX and IY could be used in front of instructions meant to work on the eight-bit registers A and L.
In February 1981 Peckett reported that the op-code 124, normally used to load A with H, would load A with the top eight bits from register IX instead, if it was preceeded by a 221 byte. Similarly, the bytes 253, 124 loaded A with the high byte of IY.
According to Zilog, IX and IY are fixed-purpose 16-bit registers. In fact they’re just duplicates of HL, and each index register can be used in two eight bit halves, as well as a 16 bit pointer. That means you can have an extra pair of eight bit registers instead of each index register, if you want them — and most assembler programmers want as many registers as they can get!
You can generate 88 undocumented but reliable instructions by prefixing single-byte 8080 op-codes with 221 or 253. This only works with 8080 codes — not with the eight-bit register instructions unique to the Z80, like BIT, SET, SLA and so on. You can’t mix index registers with HL in the same instruction, so 221 (select IX) followed by 108 (LD L,H) loads IXL with IXH, rather than L with IXH or IXL with H. This isn’t much of a surprise, as the prefix seems to switch HL off and replace it with IX for the duration of the next instruction.
I’m sure there are other secret and useful instructions in the Z80, but those are the only ones I’ve come across. Most assemblers will reject the non-standard mnemonics I’ve used — you’ll have to enter the instructions as byte values.
The Picturesque Editor Assembler, recently repackaged as The Code Machine by Discovery lets you use all these instructions in your programs. It uses the mnemonic SLL for the new shift instructions, and calls the index register sections IXL, IXH, IYL and IYH.
Unfortunately The Code Machine monitor program doesn’t disassemble the instructions correctly. You may come across some of these op-codes in routines like Speedlok, which are designed to be hard to hack.
The Z80 has a few other secrets. Almost a decade ago a hacker called Adrian Kennard realised that its possible to write Z80 instructions that execute their own operands, making them very hard to disassemble!
The four conditional relative jumps test the flags and then treat the values of the next byte as an offset to the next instruction to be executed if the condition is true. The offset is relative to the address after the conditional jump. So an offset of minus one has the logical but bizarre effect of sending the computer back one byte, so that it re-reads the offset, this time treating it as an instruction.
It just so happens that the value minus one is the op-code of a single byte instruction, RST 56 — so this special case of the conditional jump creates a new two-byte instruction, a conditional restart! On the Spectrum, RST 56 is used to scan the keyboard and update the software clock.
The IN A,(C) instruction actually works as IN A,(BC), and is used as such by the Spectrum ROM. In other words, the value of B is written to the top eight bits of the address bus during IN instructions that use a port number in register C. Similarly, IN A,(N) puts the old value of A on lines A8 to A15, while the eight-bit port number appears on A0 to A7.
Graeme Walton has written in with further information about quirks and incompatibilities of the Spectrum +3, and at last I’ve got hold of some detailed technical information about the design changes in the machine.
In the Christmas Special I listed some of the bugs in the +3 ROM. The problems were serious, and explained why some programs lack sound and others fail when the COPY command is used. However they didn’t explain why some games ‘lock up’ when you run them on a +3, even though they work fine on any earlier model of the Spectrum.
Graeme has discovered that Arkanoid, Short Circuit and Top Gun all use code which reads information from an undocumented port in the Spectrum’s logic array. The programs contain loops which read from port 10495 — part of the original Spectrum ULA — and wait for particular values. In fact you can get the same effect by reading port 255, as the top eight bits of the port number are ignored.
The Sinclair-designed Spectrums — including the original Amstrad +2, which was essentially a Sinclair 128 in a new box — have regularly changing values at port 10495.
The value is the current attribute being written to the TV, and corresponds exactly to the number you’d read with the ATTR function. Programmers use this value to divide up the frame time evenly between several different tasks, and soak up time by waiting for it to change. The value is 255 while the border is drawn.
Unfortunately, Amstrad didn’t know about this port, and the value sticks at 255 on a +3. Switching into 48K BASIC doesn’t help, because it doesn’t change the hardware.
I have never seen the workings of this port documented, so I’m not surpnsed that Amstrad missed it out from the +3. Even so, it’s another important incompatibility in a computer with a lot of problems, and it’s hard to see how software producers will be able to get some programs working without such a facility to synchronise the code and the display.
I haven’t got any of the games affected by the +3 fault, so I can’t try commenting out the loop. In theory that will make the games work, but it is likely to give a flickering display and an unpredictable running speed. A delay loop may be better, but will probably still cause a lot of flicker. If you know or can find out more, please write in.
I’ve discussed this quirk with MGT, developers of the SAM SuperSpectrum, and they assure me that their machine lets you read the current attribute value from the port, just as on a Sinclair Spectrum.
They’ve just tied up a deal with a large semiconductor manufacturer which will produce their logic array and ensure supplies of scarce RAM chips later in the year — so the SAM development should not be hit by the chip shortages which have affected other manufacturers.
When the +3 came out last year I explained how you could access a ‘hidden’ self-test program. Graeme Walton has discovered another couple of hidden options, also accessible from the ‘test card’ which you get by holding down the BREAK key and pressing Reset.
Once the TV test card is displayed, press the keys ‘Q’, ‘A’, ‘Z’, ‘P’, ‘L’ and ‘M’ for the self-test program. The version number is shown when the program starts up — the +3 I’ve borrowed from Editorial contains version 4-0 of the test suite.
Graeme has discovered you can return to the initial menu from the test card by holding down keys ‘V’ and ‘B’ at the same time. That menu used to contain a ‘tape tester’ option on earlier Spectrum 128s, but the +3 misses it off — presumably because of Amstrad’s low-key approach to +3 cassettes, vital though they are.
Graeme finds that keys ‘A’, ‘E’ and ‘U’ pressed together from the test card call up the missing ‘tape test’ routine. On our +3 it gives a completely blank screen until you play a tape, at which point animated blocks of colour appear, rather like a colour sound-to-light display, or the loading pattern on a ZX-81. The pattern varies to reflect rhythms in the input signal, so you can get entertaining results by playing music into the cassette port and watching the screen pulse in sympathy.
It may be that there are several different versions of the +3 internal software, because Graeme says that on his +3 the combination of keys calls up a bar-graph tape tester, more like the one on the old 128.
In any case the old bar-graph tester can be called from +3 BASIC, using a snippet of code that Graeme has sent in. The relocatable code in Listing 1 calls up ROM routines that work just like the old 128 tester, with the added bonus of on-screen instructions.
If you want to use this code to re-align your tape heads you’ll need a correctly recorded test-tape, made on a reference machine. There’s no point using one of your own tapes, as the machine that recorded it may not have been aligned properly.
Graeme Walton wins this months’ Tech Tips prize, £40 worth of software of his choice. Yep, that’s right, the serene and benevolent management here have boosted the prize yet again — it was only £20 last year!
If you come up with a new tip that can be explained in CRASH, or an improvement to one of the Tech Tape routines, please write to Tech Tips and tell the world what you’ve done.
Tech Tips is your column — your chance to share expertise with the Top Spectrum techsters. There’s a prize of £40 of software of your choice for the best Tip published every month.
I’m keen to hear from you, but PLEASE don’t expect — or demand — a personal reply to your letters; there are hundreds of thousands of you and only one of me.
10 CLEAR 65499
20 FOR N=65500 TO 65520
30 READ X: POKE N,X
40 NEXT N
50 LET X=USR 65500
60 DATA 245, 175, 50, 29, 91
70 DATA 205, 0, 91, 205, 163
80 DATA 53, 62, 251, 50, 29, 91
90 DATA 205, 0, 91, 241, 201