As I understand it, the ZX81 video system, which resides in the ULA like all the rest of the machine-specific logic, works by using the CPU as an address generator: during active scan line, it lets the CPU try to fetch an opcode from video memory, grabs the opcode for itself to use as a character cell byte, feeds the CPU a NOP instead, then uses its own 3-bit counter plus the character cell byte to fetch a bitmap byte from ROM. An advantage of this system is that the ULA does not need to contain the 10-bit counter that would otherwise have been needed to address video memory.

Looking at the pinout of the ULA: https://www.sinclairzxworld.com/viewtopic.php?t=1249

It has D0-7, obviously needed, also A0-8, needed to generate 512 different ROM addresses, presumably corresponding to the 512-byte font for 64 different characters.

It also has A14-15. What does it use these for?


The only detail you’re missing is that A15 must be active in order for a processor M1 cycle to be treated as a video fetch.

The full memory map is:

  • 00003fff: ROM;
  • 40007fff: RAM, no special handling;
  • 8000ffff: RAM, with M1 cycles subverted into video fetches.

Both ROM and RAM just mirror within their areas.

That’s 16kb granularity, so the top two address lines are needed.

So, to answer more directly:

  • A15 is used as an input to the video system: only when it is active will an M1 cycle trigger the subterfuge of forcing a NOP and stealing the real opcode as video; and
  • A15 and A14 together create the ROM and RAM chip selects: if either is active then select RAM. Otherwise, select ROM.

The logic behind the scheme is that you can then use RAM to contain both machine code and video content, and the programmer can indicate which use is appropriate based on which RAM mirror the processor is fetching from.

  • 1
    Oh! Maybe I understand now: the machine only has one memory bank. But that is mirrored at $4000 and $8000. And when accessed at $4000 it functions as regular RAM from which you can run code, and when accessed at $8000 it functions as video memory. Would that be a correct paraphrase? – rwallace Jan 3 '20 at 13:30
  • 1
    Apologies for the presently terse answer, by the way; will update when I’m at a more favourable device. But yes, exactly that! – Tommy Jan 3 '20 at 13:30
  • If a ZX81 has more than 16 KB RAM, the range between 8000 and BFFF could be used for data. It can't be used for machine code to run. To trigger the video logic all display drivers (known to me) simply set A15, so a display file between 4000 and 7FFF will be addressed as C000 to FFFF. – the busybee Jan 5 '20 at 17:06

From a glance at Chris Smith's The ZX Spectrum ULA - How To Design A Microcomputer, the ULA for the Spectrum also has A14-A15. It uses these lines to identify whether the CPU is attempting to access the 16K of RAM where the video RAM is located. Changing these values when they're being read by the video circuitry would not be desirable.

On page 192, he describes thus:

During a memory operation the Z80 address bus contains a valid address from the start of T1 through T2 and T3. The ULA contention controller monitors A14 and A15 of the address bus, and if an access is made to the lower 16K RAM during T1, the clock wait signal is applied to the Z80 clock to hold it high. As the clock wait signal is active only when a video fetch is about to occur, or is in progress, the Z80 operation is suspended only when a contention condition exists.

The clock wait signal holds the CPU's clock signal high, effectively halting it until the video circuitry has finished accessing the RAM. I expect that a similar technique was used in the ZX81.

  • Ah! That does make sense for the Spectrum. But on an unexpanded ZX81, the 1K video memory bank is the only RAM. And on an expanded one, as I understand it, the onboard RAM is disabled in favor of only using the expansion RAM. So I'm not seeing how this is applicable? – rwallace Jan 3 '20 at 13:17
  • 1
    @rwallace The onboard RAM and Expansion RAM are both mapped to the same address space: within the 16K chunk from 0x4000 upwards. While the use of A14 alone could distinguish between ROM at 0x0000 and RAM at 0x4000, A15 is also needed for reasons better explained by Tommy. – Kaz Jan 3 '20 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.