We can probably trace a ton of greatly influential programmers back to Sinclair machines (Linus Torvalds used a Sinclair QL for example, I think Demis Hasabis had a Speccy.. maybe), but the original ZX Spectrum 48k stands separate from all the rest. The whole hardware architecture was a series of hacks to make the machine as cheap as possible. A few fascinating facts that come to mind:
(1) the 48k Speccy had a total of ..96KiB of memory: 16KiB of "proper" DRAM, 16KiB of ROM for its BASIC and ..64KiB of DRAM of which half of was non-functional! Sinclair was buying broken memory chips and binning them to get sets whose either the top or the bottom 32KiB worked. They could get these chips for way cheaper. Each machine would have a jumper to select either the top or the bottom 32KiB working region.
(2) Both the "graphics card" chip (the ULA, or Uncommitted Logic Array, an early form of an FPGA) and the Z80 CPU needed to read from memory. Instead of having multiplexers, the ZX Spectrum just connected the two address buses with resistors, such that the ULA would overpower the Z80 if both tried to set an address to read from. The CPU was completely unaware of this: the ULA would ..freeze its clock signal for a few clock cycles, do its thing, and then let the CPU continue with its read. It was actually slower to read from a specific region of RAM that contained the framebuffer because of this.
(3) the article describes the weird out-of-order memory layout for the screen. The reason it was done this way was because of the 4116 DRAM chips the machine was using. These were 16,384 (2^14) 1-bit memories, arranged in 2^7 rows and 2^7 columns. To address a random location, one would need to first clock in the 7-bit row, followed by clocking in the 7-bit column. If you wanted to access consecutive memory locations with the same row address, the chips had a "fast page mode", where you would only need to clock in the next 7-bit column address. The memory was laid out in such a way that would minimize row address settings.
Hacks, all the way down to the core.
paol 10 hours ago [-]
The hacks paid off though. The cheapness made the Spectrum ubiquitous across whole swaths of europe. Not only was it the first computer of an entire generation, it was the first generation where many people had a computer.
vitesse_oblige 10 hours ago [-]
Good times! I wonder if you remember this bit:
Graphics often looked a little weird, because of the hard limit of one color 'palette' (1 ink color and 1 paper color) per 8x8 pixel grid.
However, if you had cycles to spare, there was a cool hack that allowed one palette for each 8x1 pixel slice. By synchronizing with the ULA, you could overwrite the attribute row at each horizontal blanking interval.
The only time you'd have cycles to spare, of course, is when you weren't doing anything else whatsoever. But it made for pretty "press any key" welcome screens.
77pt77 28 minutes ago [-]
Some games (Turrican?) even used an hack that displayed the color brown on the screen, when no such color was part of the pallet.
praptak 9 hours ago [-]
There was also the screen border which generally had to have one color but you could use a similar trick to draw static stripes on it (ZX wasn't fast enough to change the color more than a few times per scan line, so you could not really draw more than stripes of varying width).
I remember a game that had a welcome screen which had matching stripes on the real screen and then drew some pixel patterns on it to create an illusion of drawing individual pixels on the border.
Someone 7 hours ago [-]
> Each machine would have a jumper to select either the top or the bottom 32KiB working region.
So, did anybody mod the machine by replacing the chips by working ones and making that jumper software-controllable to get 16 + 2 × 32 = 80KiB of RAM?
ZX Spectrum didn't have joystick interface. So Poland had a cottage industry to build one as cheap as possible. The best hack was to construct logic gate using germanium transistors to avoid expensive gates with 3 state output.
Connecting a printer required building yourself a Centronics interface and writing a driver for it. I recall some people managed to build floppy disk controller and connect 5 1/4 drive.
oliviergg 3 hours ago [-]
So many constraints on computers in the 80s. But so much fun trying to get close to what we had in our heads!
Big nostalgia for that era. Everything was limited, but everything seemed possible.
What got me into computers was:
A = 1; B = 5; C = A+B : C= 6
But:
A = "firstname"; B = "lastname"; C = A+B : C="firstnamelastname".
I dont know why but I still remember the revelation.
In retrospect, it was the limitations that made it so fun. The system was so simple that it was entirely knowable by a single brain, which has become enormously more challenging nowadays.
I recently ported my teaching raytracer to the Spectrum [0], not even using assembler, but the horribly slow native BASIC. It was a ton of fun! It's super slow especially when run on the original hardware, but even then I can't remember something like this from back in the day (and I'd bet something like Microhobby would have listed this as some kind of curiosity); makes me think the Spectrum's limitations weren't even fully explored. Raytracing people were probably working on beefier machines and more serious projects.
I was never into the Spectrum or any vintage computer like that, but the pico-8 fits that same gap of having an (artificially) limited system, so your code is ugly and uses two-letter variable names because you can only fit 40 characters on screen and the graphics are pixelart. But you can make something and since there's simply not the space for it, bikeshedding is discouraged.
pjmlp 12 hours ago [-]
We had no alternatives, it was either whatever we managed to get hold of, with whatever information that we could gather from the provided manuals, a few magazines, and if lucky, the local library.
Ironically, the BASIC + Assembly combo continues to this day, even if done in different tongues.
nine_k 13 hours ago [-]
ZX Spectrum was one of the few inexpensive options, especially with color support. However terrible it was, it was also very enticing, or just the only thing you had at home, and could tinker with.
stas2k 10 hours ago [-]
I still remember getting a USSR clone(Leningrad) at 5 years old. It is probably earliest memory I have.
Did not know English, could not read anything, but still spent hundreds of hours first playing, and then tinkering with it.
There was no OS to mess up, and it booted instantly to a Sinclair BASIC prompt.
js8 11 hours ago [-]
Playing a devil's advocate - if you have to scrap by with little memory and few services, you focus on your mission, not distractions like code elegance, library choices and build systems.
praptak 9 hours ago [-]
Commercial developers could afford cross development setups where the actual development happened on PCs and the code was transferred to the Spectrum, see for example:
It wasn't that bad if you put in context of its era: for example, the computer that landed on the moon just 10 or so years earlier, had 4 KiB RAM, 72 KiB ROM and was running at a speed of 40k instructions per second.
flohofwoe 9 hours ago [-]
Tbf, even a simple macro assembler gets you closer to a proper high level language dev-experience than programming in machine code. We're just not used to the idea of macro assemblers anymore because our only contact with assembly code is when staring at the messy disassembly of high-level-language compiler output.
But that's very different from working in a properly commented and 'macro-assisted' Z80 or 6502 assembly code base.
MichaelRo 10 hours ago [-]
I was in high school (about 14-15 years old) when I recall drawing lines and circles with BASIC on ZX-Spectrum and it was horribly slow. Was thinking of making some simple games and tried graphics mode but it was just too slow to achieve anything.
So I switched to HiSoft Pascal and line and circle became instantaneous but still I didn't dare program Tetris in graphics mode. So I used text/character mode, compiled from Pascal and was fast enough to play. (In regular BASIC, I couldn't make it work).
Then I installed HiSoft BASIC compiler and my regular BASIC was now fast enough for TETRIS. On the other hand if you think that in 48Kb of RAM they had to fit the video RAM about 8 Kb, the BASIC compiler, my BASIC code, the compiled code and use some RAM for stack and variables ... crazy. Fun times...
beagle3 2 hours ago [-]
The spectrum only had one mode: 256x192 1-but pixels, 32x24 palette (each 8x8 box had two colors, “paper” for a 0 pixel and “ink” for a 1 pixel).
Other computers of the time (C64, Apple II, BBC / Acorn) had distinct text vs graphics modes, although some had a user-defined font which kind of makes the distinction less firm.
But the spectrum only had a graphics mode.
tzot 9 hours ago [-]
> On the other hand if you think that in 48Kb of RAM they had to fit the video RAM about 8 Kb, the BASIC compiler, my BASIC code, the compiled code and use some RAM for stack and variables ... crazy. Fun times...
I had a Spectrum, and then when the QL got relatively cheap, I got one too. Loved 68K assembly.
Given that the 68K instructions were always a multiple of 2 bytes, in its 48K ROM you could have a maximum of 24576 instructions. Now remove the space needed for the bitmap font and some lookup tables, and in the remaining space you had:
- A multitasking operating system (no memory protection, of course), with networking (not TCP/IP of course) and media (microdrive) management, and generic channels kind of in the Unix file spirit
- A (non-re-entrant, single instance) “SuperBASIC” with procedures and functions with LOCal variables, a switch construct (SELect ON), FOR loops with epilogues that would run if not broken out of the loop, and other goodies, which SuperBASIC was also the system shell
- A collection of system calls and a system library, from windowing functions to software floating point (the 40-bit format) operations
Not having a lot of money for software but with the help of some book from the library (titled something like Assembly Programming on the Sinclair QL, don't remember exactly) I even wrote a disassembler in SuperBASIC to decode and grok the ROM. My mind was blown with the density of the ROM code.
JdeBP 8 hours ago [-]
QDOS even had non-blocking I/O at the individual read/write call level.
I had to mention this when I learned of Daniel J. Bernstein advocating, almost 20 years after QDOS, non-blocking nonblock_read()/nonblock_write() additions to the POSIX model, so that your I/O model wasn't something that you had to coördinate and share with every process that might have the same open file descriptor.
There were all sorts of little innovations in the operating systems world back then. Helios was another interesting one, with capabilities.
bitwize 9 hours ago [-]
> It's still inconceivable to me how people developed for these platforms.
Well, we didn't have Visual Studio Code, and we couldn't summon Claude to help us through the tricky bits. We used whatever tools were available and a LOT of trial and error in order to master the machine. Because computers were amazing, and having one on your desk you could play with was even more amazing.
I didn't have a Spectrum, because I'm a bloody Yank. I had a VIC-20 and later a TI-99/4A. In the States we had Apple, IBM, Tandy, TI, and Commodore, with Apple pretty much the dominant force in home computing until PCs got cheap enough. Everybody else was pretty niche, so even when affordable computers came out -- like the Timex Sinclair and Timex Sinclair 2068 (which was based on, but not broadly compatible with the Spectrum), there wasn't a huge library of software nor a large programmer/hobbyist community like there was with the Spectrum in the UK. The "bedroom coder" phenomenon was still a thing, but I think the wide availability and low price of the Spectrum enabled more Brits from a variety of backgrounds and socioeconomic strata to become "bedroom coders" than Americans, for whom home computers were pretty much expensive toys.
77pt77 31 minutes ago [-]
> Timex Sinclair 2068 (which was based on, but not broadly compatible with the Spectrum),
I had one and it came with a spectrum 48K emulator cartridge that was pretty good but had a bug in the graphics emulation.
The keyboard was much better.
jpecar 9 hours ago [-]
I still don't get what
POKE 23641,194
RUN
does on zx spectrum. And you get different patterns for different values, say 197. And wait for a minute or so to see something even more interesting.
rwmj 9 hours ago [-]
I tried this on a Spectrum emulator (https://jsspeccy.zxdemo.org/ - select 48K BASIC, then use the "O" key to enter POKE, then "R" to enter RUN).
The two bytes at that address and the one following are used by the BASIC ROM to track the command you're typing in, so maybe an artifact of how the ROM works?
jpecar 9 hours ago [-]
Yes, this makes magic on real hardware and I see it do nothing on emulators. So something really funny must be going on here ...
flohofwoe 9 hours ago [-]
I get a colorful screen pattern when I try that on my emulator (which otherwise isn't very precise though):
...you can open the step debugger after entering the command (in the menu "Debug => CPU Debugger") and see that execution is caught in an LDDR (reverse block copy) which essentially overwrites the entire RAM, and then gets caught in a loop which causes it to return to that LDDR.
The poke address 23641 is probably some state variable of the BASIC interpreter and by writing to it you're messing up the state in a way that a RUN jumps into a specific place in the ROM which happens to run that LDDR.
rwmj 8 hours ago [-]
> The poke address 23641 is probably some state variable of the BASIC interpreter and by writing to it you're messing up the state in a way that a RUN jumps into a specific place in the ROM which happens to run that LDDR.
And how does that lead to colorful flashing pattern that "collapses" some 30 seconds after it appears?
rwmj 9 hours ago [-]
Actually I got it to work on the emulator too, see updated comment.
I'm sure this is a BASIC ROM artifact. Would require disassembling the ROM to see what's going on and it's a bit too early in the morning for that :-) EDIT: See
flohofwoe's much better answer.
(1) the 48k Speccy had a total of ..96KiB of memory: 16KiB of "proper" DRAM, 16KiB of ROM for its BASIC and ..64KiB of DRAM of which half of was non-functional! Sinclair was buying broken memory chips and binning them to get sets whose either the top or the bottom 32KiB worked. They could get these chips for way cheaper. Each machine would have a jumper to select either the top or the bottom 32KiB working region.
(2) Both the "graphics card" chip (the ULA, or Uncommitted Logic Array, an early form of an FPGA) and the Z80 CPU needed to read from memory. Instead of having multiplexers, the ZX Spectrum just connected the two address buses with resistors, such that the ULA would overpower the Z80 if both tried to set an address to read from. The CPU was completely unaware of this: the ULA would ..freeze its clock signal for a few clock cycles, do its thing, and then let the CPU continue with its read. It was actually slower to read from a specific region of RAM that contained the framebuffer because of this.
(3) the article describes the weird out-of-order memory layout for the screen. The reason it was done this way was because of the 4116 DRAM chips the machine was using. These were 16,384 (2^14) 1-bit memories, arranged in 2^7 rows and 2^7 columns. To address a random location, one would need to first clock in the 7-bit row, followed by clocking in the 7-bit column. If you wanted to access consecutive memory locations with the same row address, the chips had a "fast page mode", where you would only need to clock in the next 7-bit column address. The memory was laid out in such a way that would minimize row address settings.
Hacks, all the way down to the core.
Graphics often looked a little weird, because of the hard limit of one color 'palette' (1 ink color and 1 paper color) per 8x8 pixel grid.
However, if you had cycles to spare, there was a cool hack that allowed one palette for each 8x1 pixel slice. By synchronizing with the ULA, you could overwrite the attribute row at each horizontal blanking interval.
The only time you'd have cycles to spare, of course, is when you weren't doing anything else whatsoever. But it made for pretty "press any key" welcome screens.
I remember a game that had a welcome screen which had matching stripes on the real screen and then drew some pixel patterns on it to create an illusion of drawing individual pixels on the border.
So, did anybody mod the machine by replacing the chips by working ones and making that jumper software-controllable to get 16 + 2 × 32 = 80KiB of RAM?
I googled for that, but couldn’t find it.
His book is well worth a read: https://bizzley.42web.io/?i=1
Big nostalgia for that era. Everything was limited, but everything seemed possible.
What got me into computers was:
A = 1; B = 5; C = A+B : C= 6
But:
A = "firstname"; B = "lastname"; C = A+B : C="firstnamelastname".
I dont know why but I still remember the revelation.
A good discussion about the setup for Manic Miner by the author is here:
https://www.youtube.com/watch?v=LymCezUg7HI
I recently ported my teaching raytracer to the Spectrum [0], not even using assembler, but the horribly slow native BASIC. It was a ton of fun! It's super slow especially when run on the original hardware, but even then I can't remember something like this from back in the day (and I'd bet something like Microhobby would have listed this as some kind of curiosity); makes me think the Spectrum's limitations weren't even fully explored. Raytracing people were probably working on beefier machines and more serious projects.
[0] https://gabrielgambetta.com/zx-raytracer.html
Ironically, the BASIC + Assembly combo continues to this day, even if done in different tongues.
Did not know English, could not read anything, but still spent hundreds of hours first playing, and then tinkering with it.
There was no OS to mess up, and it booted instantly to a Sinclair BASIC prompt.
https://bizzley.42web.io/assets/it_s_behind_you___the_making...
But that's very different from working in a properly commented and 'macro-assisted' Z80 or 6502 assembly code base.
So I switched to HiSoft Pascal and line and circle became instantaneous but still I didn't dare program Tetris in graphics mode. So I used text/character mode, compiled from Pascal and was fast enough to play. (In regular BASIC, I couldn't make it work).
Then I installed HiSoft BASIC compiler and my regular BASIC was now fast enough for TETRIS. On the other hand if you think that in 48Kb of RAM they had to fit the video RAM about 8 Kb, the BASIC compiler, my BASIC code, the compiled code and use some RAM for stack and variables ... crazy. Fun times...
Other computers of the time (C64, Apple II, BBC / Acorn) had distinct text vs graphics modes, although some had a user-defined font which kind of makes the distinction less firm.
But the spectrum only had a graphics mode.
I had a Spectrum, and then when the QL got relatively cheap, I got one too. Loved 68K assembly.
Given that the 68K instructions were always a multiple of 2 bytes, in its 48K ROM you could have a maximum of 24576 instructions. Now remove the space needed for the bitmap font and some lookup tables, and in the remaining space you had:
- A multitasking operating system (no memory protection, of course), with networking (not TCP/IP of course) and media (microdrive) management, and generic channels kind of in the Unix file spirit
- A (non-re-entrant, single instance) “SuperBASIC” with procedures and functions with LOCal variables, a switch construct (SELect ON), FOR loops with epilogues that would run if not broken out of the loop, and other goodies, which SuperBASIC was also the system shell
- A collection of system calls and a system library, from windowing functions to software floating point (the 40-bit format) operations
Not having a lot of money for software but with the help of some book from the library (titled something like Assembly Programming on the Sinclair QL, don't remember exactly) I even wrote a disassembler in SuperBASIC to decode and grok the ROM. My mind was blown with the density of the ROM code.
I had to mention this when I learned of Daniel J. Bernstein advocating, almost 20 years after QDOS, non-blocking nonblock_read()/nonblock_write() additions to the POSIX model, so that your I/O model wasn't something that you had to coördinate and share with every process that might have the same open file descriptor.
* https://jdebp.uk/FGA/dont-set-shared-file-descriptors-to-non...
There were all sorts of little innovations in the operating systems world back then. Helios was another interesting one, with capabilities.
Well, we didn't have Visual Studio Code, and we couldn't summon Claude to help us through the tricky bits. We used whatever tools were available and a LOT of trial and error in order to master the machine. Because computers were amazing, and having one on your desk you could play with was even more amazing.
I didn't have a Spectrum, because I'm a bloody Yank. I had a VIC-20 and later a TI-99/4A. In the States we had Apple, IBM, Tandy, TI, and Commodore, with Apple pretty much the dominant force in home computing until PCs got cheap enough. Everybody else was pretty niche, so even when affordable computers came out -- like the Timex Sinclair and Timex Sinclair 2068 (which was based on, but not broadly compatible with the Spectrum), there wasn't a huge library of software nor a large programmer/hobbyist community like there was with the Spectrum in the UK. The "bedroom coder" phenomenon was still a thing, but I think the wide availability and low price of the Spectrum enabled more Brits from a variety of backgrounds and socioeconomic strata to become "bedroom coders" than Americans, for whom home computers were pretty much expensive toys.
I had one and it came with a spectrum 48K emulator cartridge that was pretty good but had a bug in the graphics emulation.
The keyboard was much better.
POKE 23641,194
RUN
does on zx spectrum. And you get different patterns for different values, say 197. And wait for a minute or so to see something even more interesting.
The two bytes at that address and the one following are used by the BASIC ROM to track the command you're typing in, so maybe an artifact of how the ROM works?
https://floooh.github.io/tiny8bit/zx-ui.html?type=zx128
...you can open the step debugger after entering the command (in the menu "Debug => CPU Debugger") and see that execution is caught in an LDDR (reverse block copy) which essentially overwrites the entire RAM, and then gets caught in a loop which causes it to return to that LDDR.
The poke address 23641 is probably some state variable of the BASIC interpreter and by writing to it you're messing up the state in a way that a RUN jumps into a specific place in the ROM which happens to run that LDDR.
Yes, it's the least significant byte of "E LINE Address of command being typed in" in the scratch area: https://worldofspectrum.org/ZXBasicManual/zxmanchap25.html It's cool that they documented all that stuff in the manual!
I'm sure this is a BASIC ROM artifact. Would require disassembling the ROM to see what's going on and it's a bit too early in the morning for that :-) EDIT: See flohofwoe's much better answer.
http://www.primrosebank.net/computers/zxspectrum/docs/Comple...
The Spectrum ROM is a wonderful program. The numerical evaluation system was unique. Every number could be replaced by an expression.
MD content is not available