Spectrum timing information - racing the beam - why is timing important ?

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.
oldtv


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
sundial

hourglassHow much time do I have ?

Let's break down a screen frame (50th of a second for a 50HZ TV signal) into T states    



PositionSpectrum 16K / 48K / +Spectrum 128K
From start of frame to first screen byte14335 14361
From first byte of row to last128128
Left border, flyback and right border96100
Whole row (eg, start of row 1 to start of row 2)224228
Whole row * 196 rows43904  44688
Time from last row to next frame1163711852
Total T states before next frame6988870908



Contention            
                              
TugofWar


Just to complicate matters further, the Spectrum ULA chip needs to access screen memory to provide raster data, and only one chip can read memory, so when it's doing that it "locks" access to the whole lower 16K RAM - known as contended memory. If the CPU has an instruction to read or write at that time, it will get delayed because the memory is contended. If you have an LDI instruction in contended memory, to copy to and from contended memory, that's 3 CPU reads and potentially 3 contention delays. So don't do that.
To prevent wasted CPU time and tearing, avoid running code or reading data in contended memory while the raster is in the screen area. 

Contention works in an 8 T state cycle like this (48K example, 128K machine starts from 14361) - T States value shows the number of  processor cycles since the raster reached the top left corner of your screen (also the time of the interrupt)
TstatesDelay
143356 (until 14341)
143365 (until 14341)
143374 (until 14341)
143383 (until 14341)
143392 (until 14341)
143401 (until 14341)
14341No delay
14342No delay
143436 (until 14349)
143445 (until 14349)
143454 (until 14349)
143463 (until 14349)
143472 (until 14349)
143481 (until 14349)
14349No delay
14350No delay
Source https://sinclair.wiki.zxnet.co.uk/wiki/Contended_memory

Turtle Quality made an Excel to try and estimate how many T states your code will take, with or without contention, it's available here. It also contains a list of all the instructions and the time they take

MultiColour effects

Right, this is where you really need to know where the raster is...

The Spectrum has hi-res graphics (256 x 192) , but low res colour (32 x 24 of 8x8 pixel squares) . But with every 8 pixels displayed, the ULA has to read the colour of the 8x8 square from the ATTR. If your code is precise enough, you can change the colour exactly between the 1st and 2nd row being displayed. So now you can control the colour of each 8x1 pixel strip. Except you'll almost certainly run out of time trying to write a full row of attributes before the raster overtakes you. So you need your code to be as efficient as possible, minimise contention somehow and still compromise a little by limiting the multi-colour area to 18 columns or change colour every 2nd row or some other compromise.

When you've achieved all the above, you now have very limited cycles left to read the keyboard and other game logic before the next screen update.

There's a number of games using this trick to produce colourful graphics that back in the 20th Century would have been deemed impossible on the Spectrum - a couple of examples below.

Manic PietroSnake Escape
Manic PietroSnake Escape