Hopefully, this is a pretty comprehensive list of the differences between the ZX81 and Spectrum (and, to a lesser extent, the ZX80) BASICs:
- String handling
- No
FAST
and SLOW
UNPLOT
/PLOT OVER
- Additional (faster) method for storing integers
- Maths
- Multi-statement lines
- Scrolling
- ASCII
- Text display:
INVERSE
, BRIGHT
, FLASH
, OVER
, SCREEN$
- String input:
LINE
- Pixel graphics:
LINE
, CIRCLE
, DRAW
, POINT
. Also PLOT
- Colour:
BORDER
, PAPER
, INK
, ATTR
- Sound:
BEEP
- Typographical
- Files and channels
- Fixed video RAM
- Input/Output:
IN
, OUT
- Binary:
BIN
- Tape files:
VERIFY
and MERGE
. Also modifiers: LINE
, DATA()
, DATA$()
, CODE
and SCREEN$
- Faster, better tape loading and saving
- String evaluation:
VAL$
- Microdrives:
MOVE
, ERASE
, CAT
, FORMAT
- Functions:
DEF FN
and FN
- Data:
READ
, RESTORE
, DATA
- User defined characters
- Key repeat
This list (mostly) omits the enhancements when plugging in Interface 1.
Nevertheless, such a substantial list of changes looks like it could fill 7 kB of additional ROM space.
Looking at each in a little more detail...
String handling
ZX80 offered no string manipulation, whereas the ZX81 introduced n TO m
- to simplify (and reduce memory). The Spectrum continued the use of TO
, possibly with no further enhancements to the ZX81 functionality (I can't remember).
No FAST
and SLOW
The ZX81 had FAST
and SLOW
keywords, for the two modes of operation. The Spectrum did away with these modes, and hence the keywords.
UNPLOT
/PLOT OVER
The ZX81 has a third command the Spectrum doesn't have: UNPLOT
. On the Spectrum, the same effect can be achieved by using PLOT OVER
with the same x- and y-coordinates.
Additional (faster) method for storing integers
The ZX80 handled all numbers as integers. The ZX81 added floating point support but also added an "integer only" storage method, for numbers between -65535 to 65535, that was faster than the floating point storage. From Reusing code, reverse engineering and collaboration:
For the floating point routines, Vickers used a format almost identical to the 40-bit version of MBF. But he added the ability to store integer numbers in the range -65535 to 65535. The user doesn’t have to specify variable types. And it’s faster than BASICs that only store numbers as floating-point, such as Commodore’s.
The Spectrum also had this faster integer storage method. From The Complete Spectrum ROM Disassembly, by Logan, Ian; O'Hara, Frank, on page ii (in the Introduction):
The arithmetic routines
The Spectrum has two forms for numbers. Integer values in the range
-65535 to +65535 are in an 'integral' or 'short' form whilst all other numbers are in a five byte floating point form.
The present version of the monitor is unfortunately marred by two
mistakes in this part.
i. There is a mistake in 'division' whereby the 34th bit of a division is lost.
ii. The value of -65536 is sometimes put in 'short' form
and at other times in 'floating-point' and this leads to troubles.
Maths
Vickers further improved the math pacakge
... for the Spectrum, over the ZX81. How is was improved is unclear.
Multi-statement lines
The ZX81 only allowed one statement per line number. The Spectrum allowed multi-statement lines.
Scrolling
The ZX81 doesn't scroll the screen automatically like the Spectrum does, you have to use a specific command, SCROLL
.
See also the scrolling issues hinted at in the section Fixed video RAM, below.
ASCII
The ZX81 only has a limited character set with only upper case using non-ASCII values, whereas the Spectrum supports ASCII and lower case characters.
As a result, the inverse characters and half-tone "checkerboard" characters was lost on the Spectrum. However, the User defined characters, see section below, introduced with the Spectrum, and the INVERSE
text modifier, could be used to work around these "lost" characters.
Text display: INVERSE
, BRIGHT
, FLASH
, OVER
, SCREEN$
The Spectrum allowed effects to be added to text characters, using the INVERSE
, BRIGHT
, FLASH
, OVER
commands. The ZX80/ZX81 did not.
The Spectrum added a way to read a character on the display, using SCREEN$
:
The character that appears, either normally or inverted, on the television at line x, column y. Gives the empty string, if the character is not recognised. Error B unless 0<=x<=23 and 0<=y<=31.
String input: LINE
The Spectrum offered an string input that suppressed the double quotes being printed:
10 INPUT LINE A$
IIRC, Interface 1 also made use of this command by repurposing it, depending upon context.
Pixel graphics: LINE
, CIRCLE
, DRAW
, POINT
. Also PLOT
The Spectrum gains all the pixel-manipulation commands: LINE
, CIRCLE
and DRAW
.
PLOT
now means a single pixel, whereas, IIRC, on the ZX81 a "pixel" was in fact a 4x4 pixel block .
POINT
returns 1 if the pixel at (x,y) is ink colour. 0 if it is paper colour. Error B unless 0<=x<=255 and 0<=y<= 175.
Colour: BORDER
, PAPER
, INK
, ATTR
For colour manipulation the Spectrum gains the INK
and PAPER
commands, and BORDER
. ATTR
would give the display attributes of a character location on screen,
Sound: BEEP
The ZX80 and ZX81 had no sound capability (unless some funky screen blanking code was used to create a buzz in order to approximate a noise but this was a side-effect, not a feature).
The command BEEP
provided sound on the Spectrum (plus PLAY
on the 128k).
Typographical
There are minor typographical changes (ZX81 -> Spectrum):
Files and channels
- The Spectrum offers more with files, and introduces streams:
MERGE
, VERIFY
, SCREEN$
, and OPEN
/CLOSE
#
.
Additionally, for the Spectrum:
because the hardware design was incomplete, [Vickers] created a hardware abstraction layer of channels and streams.
This functionality was later "fleshed out" with the use of Interface 1 (not covered here).
Fixed video RAM
The unexpanded base model of the ZX81 used an "elastic" (and rather annoying) memory map, with the video starting at D_FILE
, that expanded (and contracted?) as the screen was filled (or emptied) (IIRC, this was due to ZX81 having to accommodate for the very limited 1 kB RAM available). It also moved around as the BASIC program residing beneath it grew or shrank.
However, if a 16 kB RAM pack was used and detected, then the video memory automatically maxed out its size.
It is better explained on page 74, chapter 27 of the ZX81 BASIC manual - the emphasis is mine:
The display file is the memory copy of the television picture. It begins with a NEWLINE character, & then has the twenty four lines of text, each finishing with a NEWLINE. The system is so designed that a line of text does not need space a full thirty two characters: final spaces can be omitted. This is used to save space when the memory is small.
When the total amount of memory (according to the system variable RAMTOP
) is less than 3 1/4 K, then a clear screen - as set up at the start or by CLS
- consists of just twenty five NEWLINEs. When the memory is bigger than a clear screen is padded out with 24*32 spaces & on the whole it stays at its full size; SCROLL
, however, & certain conditions where the lower part of the screen expands to more than two lines, can upset this by introducing short lines at the bottom.
The Spectrum was, IMHO, much easier to use as it had a fixed memory map for the RAM, with the map for the video being split into two sections:
- 6144 bytes worth of bitmap data, starting at memory address &4000
- 768 byte colour attribute data, immediately after the bitmap data at address &5800
Input/Output: IN
, OUT
The Spectrum added the ability to access the I/O space of the Z80 from within BASIC. To access the I/O space on the ZX81 you had to resort to using machine code.
According to Appendix C of the Spectrum manual:
IN
- The result of inputting at processor level from port x (0<=x<=FFFFh) (loads the bc register pair with x and does the assembly language instruction in a(c))
IIRC, these two commands were later re-purposed and used by Interface 1, depending on context.
Binary: BIN
An alternative notation for numbers: BIN
followed by a sequence of 0s and 1s is the number with such a representation in binary
Tape files: VERIFY
and MERGE
. Also modifiers: LINE
, DATA()
, DATA$()
, CODE
and SCREEN$
VERIFY
and MERGE
was introduced with the Spectrum, for enhanced tape based file storage, allowing you to verify a saved file, and to merge a saved file.
Several modifiers, used in conjunction with the LOAD
and SAVE
commands, were introduced with the Spectrum:
Saving a program using LINE
allowed a loaded program to auto-run.
SCREEN$
was used to save and load a bitmap of the screen.
CODE
was used to save and load a code block.
DATA()
was used to save and load a numeric array.
DATA$()
was used to save and load a character array.
Faster, better tape loading and saving
The Spectrum improved the routines used for loading and saving for faster performance, over those used for the ZX81.
From The Complete Spectrum ROM Disassembly, by Logan, Ian; O'Hara, Frank, on page i (in the Introduction), - the emphasis is mine:
The cassette handling routines.
It was a very unfortunate feature of the ZX 81 that so little of the
monitor program for that machine was devoted to the cassette handling.
However in the Spectrum there is an extensive block of code and now
the high standard of cassette handling is one of the most successful
features of the machine.
BASIC programs or blocks of data are both dealt with in the same
manner of having a 'header' block (seventeen bytes) that is SAVEd
first. This 'header' describes the 'data block' that is SAVEd after
it.
One disadvantage of this system is that it is not possible to produce
programs with any 'security' whatsoever.
String evaluation: VAL$
The ZX81 has VAL
Evaluates x (without its bounding quotes) as a numerical expression.
Error C if x contains a syntax error, or gives a string value. Other errors possible, depending on the expression
However, the Spectrum added VAL$
.
Evaluates x (without its bounding quotes) as a string expression.
Error C if x contains a syntax error or gives a numeric value. Other errors possible, as for VAL
Microdrives: MOVE
, ERASE
, CAT
, FORMAT
These commands required Interface 1 to be attached, I don't think that they did anything useful without it.
Functions: DEF FN
and FN
The Spectrum added the ability to define functions.
Data: READ
, RESTORE
, DATA
The Spectrum added the ability to store data in the program.
User defined characters
The Spectrum introduced 21 user defined characters, mapped to the letters keys A-U.
Key repeat
The Spectrum also had key-repeat, upon an extended key press. Which I don't think that the ZX81 had.
References
For the floating point routines, Vickers used a format almost identical to the 40-bit version of MBF. But he added the ability to store integer numbers in the range -65535 to 65535. The user doesn’t have to specify variable types. And it’s faster than BASICs that only store numbers as floating-point, such as Commodore’s.