1980's
computers like the Spectrum did not have a separate video card with
separate memory, and were designed to create a picture for a cathode
ray beam (a.k.a. raster) scanning left to right then down to the next
row, all across the screen. Because that's how screens worked back then. Trying to move too much screen data at the wrong time could mean that the beam passed over the image while you're trying to move it, leaving the upper half of the graphic not matching the lower half - "tearing". Many early games just tried to keep the screen update as brief as possible and just hope it didn't coincide with the screen being refreshed. But for smooth graphics the aim is to ensure you write your graphics either safely before or after the beam, to ensure your on screen hero was not sliced by said beam. So firstly you pay attention to the Z80 instructions table ... how many T states does that instruction take ? Can I use INC L instead of INC HL to save some T States ? Can I make the code faster without wasting too many bytes ? Can I update the graphics higher up the screen first ? Modern screens may not display the same way, but the Spectrum was built to supply images for a 50Hz cathode ray TV, and emulators copy that behaviour. So if you want to write something for the Spectrum today the screen timing issue is the same. | ![]() |
What time is it anyway ? Back in the day the there was only way to know where the raster was, the HALT command. It would wait until the next interrupt which would hopefully be at the start of a screen frame, when the raster has moved back to the very top of your screen (but could be a long wait if you have disabled interrupts ). So then you knew you had just over 14,000 T states before the raster reached the top row of pixels. More recently it's been found that reading port #0XFF on a 48K machine, will either return #FF or the current screen attribute, giving another way to work out where the raster is | ![]() |
![]() | How much time do I have ? Let's break down a screen frame (50th of a second for a 50HZ TV signal) into T states |
Position | Spectrum 16K / 48K / + | Spectrum 128K |
From start of frame to first screen byte | 14335 | 14361 |
From first byte of row to last | 128 | 128 |
Left border, flyback and right border | 96 | 100 |
Whole row (eg, start of row 1 to start of row 2) | 224 | 228 |
Whole row * 196 rows | 43904 | 44688 |
Time from last row to next frame | 11637 | 11852 |
Total T states before next frame | 69888 | 70908 |
Tstates | Delay |
---|---|
14335 | 6 (until 14341) |
14336 | 5 (until 14341) |
14337 | 4 (until 14341) |
14338 | 3 (until 14341) |
14339 | 2 (until 14341) |
14340 | 1 (until 14341) |
14341 | No delay |
14342 | No delay |
14343 | 6 (until 14349) |
14344 | 5 (until 14349) |
14345 | 4 (until 14349) |
14346 | 3 (until 14349) |
14347 | 2 (until 14349) |
14348 | 1 (until 14349) |
14349 | No delay |
14350 | No delay |
Manic Pietro | Snake Escape |
![]() | ![]() |