Why was Sinclair BASIC so slow?

I couldn’t easily find how much slowdown this might cause to Basic: everything I find has to do with running z80 code in the contended area. Perhaps there’s a way to put the Basic program up in the uncontended area and re-run a benchmark?

This seems to me to be the most likely root cause (@drogon makes the same point.) Indeed, the Jupiter ACE people left Sinclair (the company) because of the unreasonableness of Sinclair (the man.) Engineers prefer to do good engineering!

I found some more resources and reading:

Andrew Owen has a bit of prehistory and history in describing his CHLOE replacement-ROM project. Also a text file from him here.

Another history at Retro Isle.

A collection of commented ROM disassemblies here for the ZX series.

And an explorable hyperlinked annotated disassembly of the Spectrum ROM here cued up to the NEXT machinery.

A 6502 implementation doesn’t have to do it that way. Lets remember that these (MS) BASICs were derived from Micro Softs original “Altair BASIC” for the 8080 and as I understand it, naive translation techniques were used.

I’m in the process of hand re-coding some very old code from a very old CPU into 6502 and if I blindly followed the original code, I think the 6502 code would be twice as large and 4 times slower than the original - but it’s taking time and when you’re under time/money/market pressures as I suspect Micro Soft (and every other micro maker) was back then, short cuts will be be taken…

-Gordon

Regarding contending memory access for screen and programs, this is found on other systems, too.

E.g., on the PET (yes, I know, sorry for coming back onto this, again, it’s just something I’m familiar with), the first models without a CRTC chip printed only during V-BLANK, in order to avoid “snow” on the screen, resulting from clashing memory access. But it hasn’t the same impact on the overall performance.
Is it just that Sinclair didn’t limit this to any contended areas of the address space?

*) The resulting slowdown is actually remarkable, compare this ML implementation of the famous “10 PRINT” maze, once using the print routine of BASIC 2, and once this of BASIC 4, which eventually dropped that throttle, since new PETs came with the CRTC chip:

BASIC 2 (not much faster than BASIC, all the speed advantage is consumed by having to wait for V-BLANK to put anything on the screen): https://masswerk.at/pet/?run=asm-maze-bin&rom=2

BASIC 4 (several times faster) : https://masswerk.at/pet/?run=asm-maze-bin&rom=4

Hum. If you have a look at MS BASIC on the 6502, PLA and PLH are all over the place, and, where not, crucial data is temporarily stored in zero page locations. I still think, a Z80 implementation could find some speed advantage by strategically assigning registers.

Edit: As far as I know, the Acorn Electron had the same kind of ULA / CPU clash when it came to accessing memory and Acorn missed out on limiting this to the address ranges that were actually used for screen memory. So this would be another example, which is actually due to the hardware implementation and not the software. (There’s a mod, which limits this to where it’s actually needed, and apparently effects a considerable speed-up.)
But, if this would be the same on the Sinclairs, this should affect any kind of code and not just BASIC.

Spectrum certainly suffered from slow floating point handling, and no integer shortcuts. There was room in the ROM for int shortcuts but they were presumably happy the basic was sufficient or didn’t have time. If you want a fast basic take a look at the Newbrain, it’s basically a JIT engine.

By PC days this didn’t really matter anyway as Microsoft would sell you a Basic compiler.

MS Basic is slow on Z80 in part because it’s 8080 not Z80. The Z80 BBC Basic is much nicer, Z80 based and with all the BBC basic features also smaller.

2 Likes

What BASIC was it that would work on 8080 and not a z80?
They did some weird stuff with the flag register.

I was reading about that… MS’ first Basic? Used the parity as a test… here we are:

Altair Basic has a FCompare at 0A4C that compares two floating point numbers. It returns
one of the following values:

  • 0x00 for zero
  • 0x01 for greater than zero
  • 0xFF for less than zero

That’s very logical. Now you can simply test the sign flag or zero flag to jump according to the result.

But in two instances, at 0B63 and 0C03, it is followed by a JP PO (jump on parity odd) instruction, that will jump if the result is greater than zero (as 0x01 is the only one of these three values that has an odd number of ‘1’ bits in the byte)

From

1 Like