2019-04-01: The table describing memory contention for Z80 instructions is replaced by a link to the FAQ Sinclair Wiki. Spectrum games are often easily recognizable by their garish colours and colour clashes. Or, when too much colour clash would have ruined the game (for example in isometric games like Knight Lore), monochrome game scenes. But there are games where apparently impossible colour effects are created, like in the examples below: The principle behind these effects is that the program keeps track of the exact position of the TV electron beam and updates the picture in perfect time so that the colour clash effect is negated. A good (and easy to understand) example of this is the full screen horizon in Aquaplane (see above). This effect can be achieved by keeping the border cyan-coloured until the beam reaches the end of a certain row and then change the border colour to blue. Again, when the beam starts over from the top left corner, the colour is changed back to cyan and so on. Of course, the same mechanism is behind the striped border appearing during tape loading, due to the fact that the border colour is updated with a high frequency to represent the data that is read from the tape.
To enable these kind of effects in an emulator, there are basically three things to handle:
The electron beam In the earliest incarnations of the emulator I updated the display once per interrupt frame, which worked fine for most games but of course not for the special effects described above. The optimal solution would be to update the screen bitmap one byte at a time at the exact same pace that the electron beam would sweep over the screen. Sadly, I haven't been able to do this yet without ruining the emulator's performance, but I can do one pixel row at a time with the correct pace. Update 2018-01-31: The screen is now updated one byte at at time in time with a simulated electron beam (not in debug mode yet though). Since the Z80 emulation in it self is much faster than a real Z80 processor, the emulation is done in "bursts" but paced so that the correct number of instructions are processed every 1/50:th. second. The length of each instruction is measured in processor periods - T States. The electron beam takes 224 T States to cover one screen row, so the principle is to trigger a screen row update every time enough instructions have been processed so that 224 T States have passed. The timings of the actual Spectrum screen update process is extensively covered by Chris Smith on his site www.zxdesign.info. The timing of the interrupt process The timing of the interrupt process is well known (in Interrupt mode 1, the process takes 13 T States and in mode 2 it takes 19 T States). The only thing needed here is to add these numbers to the number of T States processed by the Z80 so that the screen update process is triggered at the correct moment. The timings of the Z80 instructions The timings of the Z80 instructions are well documented so that is not a problem, but the Spectrum has a peculiarity which is essential to take into account if perfect timing is to be achieved. When the ULA (or the gate array in the +2A/3 models) reads display data from RAM to draw on the screen, the Z80 can't access the lower part of RAM 0x4000 - 0x7FFF, so the Z80 is paused every time a byte of screen data is read. This happens regularly at specific points during every frame and effectively slows down the Z80 somewhat. The effect is called memory contention and is explained in the FAQ Sinclair Wiki and at World of Spectrum along with a similar effect - I/O contention - which concerns read/write to I/O ports.
0 Comments
|
Archives
November 2020
Categories
All
|