On the ZX Spectrum 48k the first 16k of memory (0x4000-0x7FFF, 16384-32767) is contended with the ULA taking priority. The Z80 will be halted accessing memory until the ULA completes and releases the memory bus. There are some errors in early ULA revisions which could cause the 'dot crawl' and 'snow effect'. 'dot crawl' could be fixed by hardware modification.
The issue is discussed here.
The original 128k had an error in its implementation, a variation from the specification, which was carried over to the +2.
The Spectrum +2A/+3 caused issues in software due to the contended\non-contended status of memory banks being swapped causing programs that rely on this behaviour to behave differently, not work at all or not to be synchronised as intended e.g. using techniques that cause the software to miss the vertical blank. This was caused by Amstrad engineers correctly implementing the 128k specification.
In my opinion the contended memory differences on the +2A/+3 should have never got past Amstrad's QA when they designed those computers, especially since the 128k and +2 had an established user base and games that relied on this behaviour. Perhaps, they should have retrospectively changed the 128k specification?
There is a good list of affected games here.
Notable games include Arkanoid which was fixed in the Hit Squad release, Spellbound, Knight Tyme and Terra Cresta. Sometimes programmers used the floating bus to detect an attribute at the end of the screen to determine the vertical blank area but this did not work the same on the +2A/+3 ULA. These issues are not just due to contended memory differences, for example Joffa Smith considered Terra Cresta to be unfinished and full of bugs.
The Z80 can only address 64k of memory so on 128k machines to access the upper memory banks they have to be paged into memory.
The 128k can flip screens between banks 5 and 7 for double buffering allowing easier flicker free animation. See here.
This table has been copied from James McKay's web site. It illustrates the point better than I could describe it. The example usage column is based on the types of data that should not need exact timing to work.
Bank | 128/+2 | +2A/+3 | Contended | Example usage |
0 | Un | Un | Same | Code/Data |
1 | Con | Un | Different |
Sprites/Spritemap |
X2 | Un | Un | Same | Code/Data |
3 | Con | Un | Different |
Tile/Tilemap |
4 | Un | Con | Different |
Strings |
X5 | Con | Con | Same | Screen/Code/Data |
6 | Un | Con | Different |
Music? |
7 | Con | Con | Same | Screen/Compressed bitmaps? |
In BASIC the "silicon disk" can be used to access the memory banks. This can be useful for example loading Melbourne House Music Box 128k tunes into memory. The limit of the "silicon disk" is 64k.
LOAD "tune0" CODE : SAVE !"tune0" CODE 60000,5024
LOAD "tune1" CODE : SAVE !"tune1" CODE 60000,5024
CAT !
ERASE !"filename"
See page 131 in the ZX Spectrum +2 manual.
This can be called repeatidly filling memory banks with the tunes and then set the maximum RAM address to be used by BASIC:
CLEAR 60000
This worked in a demo I wrote but logically it should be CLEAR 57999 to prevent BASIC overwriting memory used by the music when it is paged into memory at 58000.
To replay:
LOAD !"tune0" : RANDOMIZE USR 58000
I assume the Melbourne House Music Box 128k replay routine uses absolute addressing from 58000. All tunes in the Music Box 128k examples were less than 5024 bytes.
This is a similar document I discovered:
Spectrum Compatibility IssuesBack to index.