Copyright 1984-1989 Simon N Goodwin

(( SUB: Please proof the answer on floating-point maths very carefully, and be wary of cutting it - it deals with a fairly intricate but VERY COMMON question. Please make sure that the response headed 'Atomic fusion' is run ASAP, as it follows on from a question printed in March. Thanks. ))

Computer Answers is PCW's help column. We offer advice about all kinds of specific hardware and software problem, through the pages of the magazine. We also welcome further information in response to published queries.

This is a common problem. Your suggested solution - scaling the number up, losing a few digits and scaling it back down - wil generally work but it is slow, potentially unreliable and restricts the range of numbers you can use, because there is a risk that a large number may be scaled beyond the number of digits that can be stored precisely.

To understand the problem, and the best solution, you need to think a bit more about fractions, numbers and the way a computer works. In the interests of clarity, albeit at the risk of boring you, I'll explain things from first principles.

In the 'decimal' arithmetic system which we use today, unlike with Roman numerals, the value of a given digit depends upon its position. By convention, a digit in a certain position represents ten times the value it would in the position to the right, and a tenth of the the value of the same digit written to the left. If you want to write a whole number - a number with no fractional part - you can always represent it exactly using this scheme; you just write down the number of units, tens, hundreds and so on up until the answer is complete.

We put a decimal point after the digit representing a certain number of units. Thereafter, each digit represents a certain number of tenths, hundredths and so on.

Some fractions cannot be written precisely in decimal, however many digits you use. One obvious example is a third, where you need an infinite number of 'three' digits after the point in order to represent the fraction precisely. Another example is the fraction one seventh, where you must repeat the digits 142857 over and over again after the decimal point. The more digits you use, the more accurate the result; but you can never represent either of these fractions exactly using the decimal scheme.

So far this may seem obvious and irrelevant. But we have established that decimal arithmetic cannot represent some fractions precisely.

Now imagine a numbering scheme where the value of each successive digit was three times that of the same digit written to its left. The columns then go (for example) nines, threes, ones, thirds, ninths, and so on. Thirty would be written 1010.

If we use this numbering system, the fraction a third CAN be written exactly - as 0.1 (the one after the point represents one third). Similarly one ninth can be written exactly as 0.01 - and one ninth is another number that could not be written precisely with any number of decimal digits.

This system is called 'base 3' because the ratio of each digit position to its successor is three. Only three posible values are needed for each digit position. Counting goes 0, 1, 2, 10 (one three and no units), 11, 12, 20, 21 and so on.

If we make the 'base', or ratio of position values, seven, we must allow each position in a number to represent up to seven values (digits from 0 to 6). Then we can write a seventh (.142857 and so on in decimal) exactly as 0.1. We still need an infinite number of digits to write a third in base seven - but this time the sequence consists of '2' digits. A third, in base seven, is .2222222 recurring! Check this by adding two sevenths, two 49ths, two 443rds (443=7*7*7) and so on.

Modern digital computers work with 'binary' or base two arithmetic. This is because it's easy to make electronic circuits work with two states - on and off, or 0 and 1 - rather than three, seven or ten. It follows that halves, quarters, eighths and so on can be stored exactly in a few bits (0.1, 0.01 and 0.001 respectively).

Fractions that can be made up from reciprocals of powers of 2 (1/2, 1/(2*2), 1/(2*2*2), 1/(2*2*2*2) etc) can be stored exactly - three quarters is .11 in binary (a half plus a quarter). Other fractions cannot. A third in binary is written 0.01010101 etc. Again, you can easily check this if you don't believe me.

Humans tend to use fractions like tenths and hundredths a lot, because they're used to decimal maths. But a tenth, when written in binary, is an infinite sequence: 0.00011001100110011... Unsurprisingly, a hundredth is also an infinite sequence, if written in binary.

'Double precision' maths just gives you some extra binary digits to play with - as the 'exact' number goes on for ever, this won't help you. Fractions of ten cannot be represented accurately in any number of binary digits. That's the problem.

Unfortunately it's not practical to make computers with ten levels from 'off' to 'on', and process decimal digits directly - there's too much risk of confusion between similar levels.

Of course, you can use groups of binary digits, or bits, to represent each decimal digit. This scheme is called Binary Coded Decimal, or BCD for short. Four bits are used to store every decimal digit. This format allows exact decimal fractions to be stored, but BCD processing is slower and more complicated than binary. BCD values also need more space than binary for a given degree of accuracy.

In the days long before micros, IBM made a computer designed to work entirely with BCD values, but the idea didn't catch on. Nowadays, Atari's eight-bit micros use BCD maths, and so does Zilog's obscure MCZ range. Both machines are mathematical sluggards as a result. Pocket calculators don't have to be as fast, or store so many numbers, but they do need to appear precise, so they often use BCD.

You can avoid all problems with binary arithmetic if you follow one simple rule! Always work in WHOLE UNITS. It is only fractions that cause problems, so if you make sure that you work in pence, or cents, or whatever your basic unit is, you'll never get the wrong answer, so long as you stay within the number of digits the machine can hold accurately. Try to avoid division except by factors, or fractional multiplication - these will always give approximate results. Be sure to round numbers consistently thereafter.

You must use string input statements to read numbers, so that floating-point approximations never get a chance to creep in. Check that the decimal point is in the right place in the input, then remove it, to get a whole number which you can process without problems. Insert the decimal point - using string operations, once again - before you print results.

So far I've only suggested a solution for accountants and other professional pedants. Scientific users, and others who need fractions to model the real world, should not be upset by this discussion. When you're working with arbitrary fractions, binary arithmetic is no less accurate than decimal. Indeed, it packs more accuracy into a given amount of memory than other schemes, such as BCD.

As I write Alan Sugar is trying to find out what the QL is, and the future of the machine - at least in its Sinclair guise - is in some doubt. However it seems likely that QL compatible systems will pop up, as you are quite right in saying that it's the basis of a powerful, expandable system. The multi-tasking operating system, QDOS, is faster and more flexible than the ST's TOS, so it is very easy to 'bolt on' an alternative user interface; Eidersoft (0708 851099) offer an attractive ROM-based icon package called ICE, which costs £24.95; WD Software (0534 81392) sell JOSS, a simpler pointer-based file handling interface, for £15. Both utilities multi-task, unlike GEM.

Sony 3.5 inch drives expect the same signals as Shugart 400-series drives. They can be connected to the same controllers and you can even mix Sony drives and the 5.25 inch Shugart variety on a single system. However the software needed to read each format differs, because they use different rules when allocating space for files.

The Atari ST uses a 'standard' CP/M-68K format, which means that Atari disks can be read by popular MSDOS computers. The Amiga goes its own way and uses a special format in which each track (concentric ring of data) on the disk is used as a whole, rather than divided into slices or 'sectors'. This allows data to be stored very densely, but it means that special software is needed to read the disk.

Amazingly enough, the Enterprise can read CP/M disks as well as the MSDOS variety. The 'main' disk operating system, EX-DOS, held in ROM, uses the MSDOS 1.0 format so it can read disks generated on an IBM PC, Apricot, Nimbus or Atari ST, for example. Enterprise also supply another system, IS-DOS, at no extra charge; this system is held in RAM, like CP/M, and is capable of reading and writing CP/M 80 disks. Both systems support 5.25 inch drives and the 3.5 inch variety, as explained above.

IS-DOS is designed to be compatible with CP/M version 2.2; it expects programs to be on MSX-DOS disks. IS-DOS gives a 56K Transient Program Area, which is large enough for virtually all CP/M 2.2 programs, and all the CP/M system calls are supported. Of course, IS-DOS is not exactly the same as CP/M, so 'badly behaved' programs may run into problems - the reserved fields in File Control Blocks have special meanings in IS-DOS, and the CP/M BIOS jump table is not in the usual place. In practice this shouldn't affect properly-written programs, but I'd advise you to 'try before you buy' if you really need to run a specific CP/M package. Enterprise can be contacted on 01 739 4282.

There's not much difference between an 80 track disk drive and a switchable 80/40 track device. In essence the switch just tells the drive to step twice as far from one track to the next when reading a 40 track disk. The number of tracks per inch is 48 for 40 tracks and 96 for 80 - so less than an inch of the radius of the disk is used to store data in either case.

The exact hardware change to convert an 80 track drive into a switchable model will depend upon the brand. It is worth comparing an 80-track only drive with a switchable unit from the same manufacturer; often the circuitry will be identical and the only difference will be the switch, which you can add yourself if you're feeling confident.

You can generally read a 40 track disk on an 80 track drive without the need to make any hardware changes; all you have to do is tell your disk software to step twice from one track to the next. Most popular disk operating systems can be patched or configured to do this.

Writing to a 40 track disk with an 80 track drive is not so easy. It can be done, but the different mechanical dimensions of an 80 track drive mean that the resultant recording may be less reliable than if it were produced by a 'proper' 40 track drive. The same goes, of course, for switchable 40/80 track drives, which are really designed to be used in the 80 track mode. Everything should be fine if you always use the same type of 40-track drive when formatting and writing data to a specific disk.

Peterson Electronics Ltd, of Academy Street, Forfar, Tayside DD8 2HA, specialise in Sharp interfaces. They sell the unit you need for £99 plus VAT. The price includes appropriate software, including a modified BASIC interpreter.

Homepak is an American package which only runs on machines with the 6502 processor and a substantial US following - the Apple 2, Atari 800 series and Commodore 64. It is published in Europe by Software Express International (021 384 5080) and distributed by Ariolasoft of Suite 105/106, Asphalte House, Palace Street London SW15 5HS (01 834 8507).

The closest equivalent to this package for the Amstrad is probably Mini Office 2, from Database Publications; the Gemini range of business software is probably also worth a look. Both are regularly listed by PCW advertisers.

The Z80 can actually address 65536 ports, rather than the 'offical' 256. As you must know, the OUT (N),A instruction puts the value N on the lower eight bits of the address bus and the value in the accumulator, A, onto the data bus.

The instruction OUT (C),A similarly puts the value of the C register on the low half of the address bus and the data in A on the data bus - but it also puts the value of register B on the other eight address lines, so the instruction really works like OUT (BC),A. IN A,(C) works the same way, so you can access 256 times as many ports as normal if you use the (C) instructions, set BC rather than C, and decode the required address lines. The Spectrum uses this trick when reading the keyboard, as you can guess if you read Chapter 23 of the original, much lamented, Spectrum manual.

That said, the decoding of signals inside the Spectrum has been kept extremely simple - some would say crude - so that many port addresses are denied to you. In particular, all port addresses which leave A0 zero select the ZX82 ULA, which controls video, the keyboard and cassette ports. If A1 is zero the ZX printer is selected; A3 and A4 select the ZX Interface 1. I've no idea what happened to A2, but Sinclair reserve it anyway. You don't want your hardware to interfere with Sinclair's, so you must use port addresses from 31 upwards - 31 is the lowest number with bits 0 to 4 all set to one.

Most cheap interfaces, such as the Kempston joystick and Interface 1, just decode A5, and expect software to read and write port 31. This will probably suit you, unless you want to decode more than one byte. Before I discuss the wiring, I'll deal with the signals you ask about.

IORQ is low when I/O devices are being addressed (the fact that the signal is active low is often signified by a horizontal line above the name). In contrast, MREQ is low when memory is being addressed or refreshed.

External devices should pull BUSRQ low when they want access to the bus, without interference from the processor. They should not try to write to the bus until the processor signals its acceptance by pulling BUSACK low. If ROMCS is pulled high the built-in 16K ROM disappears from the memory map, so that Interface 1 or some other device can substitute a different ROM. This is how the Spectrum allows extra, 'shadow' ROMs to fit into its 64K address space.

Assuming that, as is normal, your electronics is turned on by a logic 'low', you can use a three-input OR gate to combine IORQ, A5 and either RD or WR (depending upon whether you want to ReaD or WRite). When the Spectrum performs an OUT instruction to port 31, WR, A5 and IORQ all become 'low' at the same time. IN from port 31 sets RD, A5 and IORQ low. It is up to your electronics to snatch or present a data value on the Data bus at the appropriate moment. An eight-bit tri-state latch will do the trick.

This explanation should be enough to enable you to connect simple gadgets to the Spectrum - if you need to know more I suggest you get a copy of the Spectrum Hardware Manual by Adrian Dickens, published by Melbourne House.

Previous column ComputerAnswers Next column ComputerAnswers