helpline |
Andrew Hewson explains how you can convert your programs to run on a different machine
PROBLEMS of converting programs written to run on one machine so that they run correctly on another are the subject of a number of queries. Correspondents who have raised the topic include Shawn Woodhouse, Chris Fowler, and Glen Lewis. Most requests concern the conversion of ZX-81 programs to run on the Spectrum but Fowler in particular asked for details on the conversion of ZX-80 programs.
Sinclair Basic is not upwards-compatible, i.e., it is not necessarily possible to transfer a program written for the ZX-80 on to the ZX-81 or Spectrum. Usually, however, only a relatively small number of alterations is required. The converse is not true, because generally a program written for a more sophisticated machine will use facilities which are not present and cannot be emulated on a predecessor. Thus I have assumed readers are interested either in converting ZX-80 programs to run on the ZX-81 or converting ZX-81 programs to run on the Spectrum.
All the software facilities available on the ZX-80 can be mimicked on the ZX81 but the latter machine is less economical of memory space as a consequence of its greater sophistication. For example:
The ZX-81 uses 85 bytes more in the systems variables area; the ZX-81 requires five bytes to hold the value of a variable, thus permitting the use of non-integer numbers, compared to the two bytes used by the integer-only ZX-80. A calculator stack therefore is required; constants in a ZX-81 program are held both in their character and in their numeric form so that an extra six bytes per constant are required; two bytes per program line are used by the ZX-81 to hold the line length.
There is no equivalent usage by the ZX-80. Hence it will often be necessary to prune a 1K ZX-80 program to load it into a ZX-81.
'Usually only a small number of alterations is required' |
All ZX-80 commands and functions have exact counterparts on the ZX-81 except for the TL$ function, the DIM command, the division operator and the RND function. These are dealt with as follows:
The TL$ function is a special case of the ZX-81 slicing facility and is replaced by (2 TO). For example:
LET A$= TL$(A$) becomes LET A$=A$(2 TO).
Array indices start at 0 on the ZX-80 and 1 on the ZX-81 so that
DIM B(5) PRINT B(0)
is meaningful only on the ZX-80. Hence one is added to every array subscript.
Numbers are converted to integers explicitly on the ZX-81 using the INT function before division. For example:
LET B=B/5 becomes LET B=INT (B)/5
The ZX-80 random number function RND (N) generates a random integer between 1 and N inclusive, whereas on the ZX-81 RND generates a random number in the range 0 to 1. Thus, for example:
LET A=RND(N) becomes LET A=I+INT(N*RND)
The character codes used by the ZX81 are listed in appendix A of the operating manual. The codes for both letters and numbers in both normal and inverse video are the same as those used by the ZX-80 but the remainder are mostly different. Table one lists the ZX-81 equivalents for the non-alphabetic or numeric codes used by the ZX-80. Reference should be made to the table when converting CHR$ or CODE commands.
|
The ZX-80 uses fewer system variables than the ZX-81 and most of them have direct equivalents as listed in table two. Note that the variables area occurs below the display file in the ZX-80 but above it in the ZX-81 and so conversion of a program which manipulates the VARS, D-FILE and DF-CC variables is particularly difficult.
|
On the ZX-80 the FRAMES counter is incremented 50 times per second, whereas on the ZX-81 it is decremented, except bit 15, and that difference should be taken into account during program conversion.
Just as the ZX-81 uses more RAM space than the ZX-80, so, in turn, the Spectrum uses more than the ZX-81. The principal reason is the high-resolution Spectrum display which uses 6,912 of the 16,384 bytes in RAM in the 16K Spectrum, compared to 792 bytes used by the 16K ZX-81. So it is unlikely that a full-size 16K ZX-81 program can be adapted to run in a 16K Spectrum.
Table three lists the ZX-81 character codes which have a direct Spectrum equivalent. In a few cases the character is different, although the function is the same, in which case both versions are shown in the table. For example, the exponentiation operator is ** on the ZX-81 - code 216 - and ^ on the Spectrum - code 94.
|
Much of the software which runs the calculator in the Spectrum has been copied straight from the ZX-81 and that is reflected in the manner in which the character codes in the two machines, although dissimilar, march in step. The ZX-81 codes for AT, TAB, CODE through to NOT are all 21 more than the codes for the same characters on the Spectrum. It is intriguing to note that the VAL$ function, which is present on the Spectrum - code 174 - but is not present on the ZX-81 logically would have had a ZX-81 code of 195, a code which is "not used" according to appendix A of the ZX-81 manual.
Bearing in mind that the ZX-81 was designed and built long before the Spectrum, the implication is that Sinclair intended that the ZX-81 should have a VAL$ function but it was omitted at the last minute.
|
Six half-tone graphics characters in the ZX-81 do not appear in the Spectrum character set but it is a straightforward matter to create user-defined characters as required. The data for each of the characters is listed in table four. Five more ZX-81 characters have no Spectrum equivalent:
It is unlikely that any of the first three would be used explicitly in a program and so no substitute is given. The FAST command turns the ZX-81 display, speeding program execution by a factor of about four and the SLOW command turns it on again. Those commands can almost always be omitted when a program is transferred to the Spectrum, except when the FAST command has been included to prevent the user inspecting the display, in which case CLS can be substituted.
Finally, there are four characters which require special substitutes. They are "" - the paired double quotes character - SCROLL, PLOT and UNPLOT. They are dealt with as follows:
The paired double quotes character, which denotes a string within a string, is replaced by two successive double quotes characters.
The SCROLL command, which moves the display up by one line, is replaced by INPUT;.
PLOT X,Y is replaced by PLOT 4 * X + 2, 4 *Y + 2. The latter is not identical because the Spectrum pixel size is much smaller and the point will appear slightly off=centre but the difference is unlikely to be important.
UNPLOT X,Y is replaced by PLOT INVERSE 1;4*X + 2,4*Y + 2.
'It is essential to understand the function of the code' |
Table five lists the ZX-81 system variables and the Spectrum equivalents. There are several points to be noted:
The ZX-81 system variable D-FILE at 16396 which points to the beginning of the display file has no Spectrum equivalent, because the Spectrum display lies at the bottom of RAM at address 16384.
The FRAMES counter is two bytes long on the ZX-81 - and bits 0 to 14 only are used - and three bytes long on the Spectrum.
The COORDS variables are different, reflecting the difference in the PLOT resolution in the two machines.
The ZX-81 printer buffer, PRBUFF, is 33 bytes long and lies within the system variables area starting at address 16444. The Spectrum printer buffer is 256 bytes long, so that it can hold high-resolution characters, and lies below the systems variables area.
|
A word of warning. It is not possible to guarantee that a given program can be transferred from one machine to its successor. If the program author has made use of PEEKs or POKEs, it is essential to understand the function of his code on the original machine before designing the equivalent to run elsewhere. Usually that means entering the code into the first machine and analysing it dynamically.