I have ZX Spectrum+ 48k (board issue 6a) with writing to memory issue. When I try to write a value by POKE command to address 49152 (C000h) then it overwrites additionally value with address 16384 (4000h). See also attached screenshots. Any thoughts how to fix this?

enter image description here enter image description here


2 Answers 2


As pointed out in the other answer, $4000 is indeed the screen memory - so, if you print something to the screen from your BASIC program (which you do), your test program will indeed change that memory in other ways than you seem to expect.

If you want to PEEK and POKE starting from 16384, make sure your program doesn't print to the top line of the screen, for example by adding a line


That will produce much less confusing results and give you the first 32 bytes from 16384 to play with (as long as your screen doesn't scroll).

If the screen output you show is generated from the program, then your symptom is indeed a bit different from what you have analyzed (it's apparently not the write that goes wrong, but in fact the read):

You seem to print a "0" to the first screen position in line 10, so PEEK($4000) in line 20 should indeed return 0 (the pixel pattern of the empty top line of the "0" character), which it doesn't. This indicates your PEEK in that line 20 does indeed not read $4000, but in fact $C000 - or something entirely different. This hints to the /RAS and /CAS generation for the upper memory being at fault. If the write had gone wrong, you should have been able to see a black overbar on the topmost "0" character reflecting a 255 at 16384.

/RAS and /CAS for the upper memory are (unfortunately) generated from A15 and some control signals by the ZX8401 (a custom IC) in the later Spectrum issues (there used to be discrete logic, simpler to repair in earlier revisions). The RAS line passes the IC24 inverter, which could be another source of fault. This assumes you haven't messed with some other parts of the system (like the "TI" and "OKI" jumpers) which could confuse the 8401.

After some clarifications:

Your problem doesn't seem to be with upper, but with lower memory address decoding. Your real problem seems to be that the ULA (IC1) doesn't seem to be taking A14 into account when it decodes lower memory addresses for write (the ULA does the low memory address decoding totally independently from the 8401, which does the upper memory decoding.) When A14 is asserted, the ULA shouldn't generate lowmem RAS and CAS - apparently it does, however. There's two possible reasons that A14 is ignored:

  1. ULA is toast. This can easily be, the ZX Spectrum ULA is known to fail. It is, however, relatively unknown (at least to me) that an ULA is failing partially. All cases of defective ULAs so far I've only seen them failing completely (resulting in a totally non-functional computer).
  2. A14 doesn't reach the ULA at all. This would lead to your symptoms. When the ULA can't see the address line at all, it would assume it always low, thus always asserting low memory RAM select. Check continuity from the CPU pin 4 to the ULA pin 36. Maybe the ULA socket has a problem. A14 to ZX8401 seems to work though, so the problem can only be on the short path between 8401 and ULA.
  • Yes. I can see black dash near the left top corner when writing a value to $C000. Also can you explain when "TI"/"OKI" jumpers placed on Issue 6A board?
    – vikkk
    Aug 28, 2023 at 13:09
  • That black overbar is not on your screenshot. Anyhow, if you can see it when POKING to $C000, then clearly the write goes wrong. The TI/OKI jumpers are directly in the middle of the PCB near IC 27. The jumpers must match the DRAM type (rather the vendor) you have in the upper16k of memory. Explained here: blog.retroleum.co.uk/electronics-articles/…
    – tofro
    Aug 28, 2023 at 13:40
  • Did you change the upper RAM chips? If you did, you probably have to set the jumpers according to the vendor and chip types.
    – tofro
    Aug 28, 2023 at 13:49
  • It is not on my screenshots due to line 40. Current upper memory chips are TMS4532-20NL4.
    – vikkk
    Aug 28, 2023 at 16:44
  • Ignore the complete upper memory stuff above. Your problem seems to be in lower, not upper memory addressing. Apparently the ULA doesn't see (or ignore) A14.
    – tofro
    Aug 29, 2023 at 7:33

4000h is in the screen memory area and is going to get overwritten when the screen is updated, so only write here if you want to update the screen

you need to use the clear command to limit the basic memory then you can peek and poke the high memory locations

  • In an emulator this code works correct. This is some hardware issue (I can successfully load only small programs due to this memory issue) but don't know what I need to replace (CPU, ULA or some other chip). Also test program rebooting computer on a high memory test.
    – vikkk
    Aug 28, 2023 at 5:55
  • 1
    It is unlikely your code works like you seem to expect in an emulator. The PEEK (16384) in line 20 should indeed return 126. This PEEK peeks the first byte in screen memory, which at this point in time should contain the pixel pattern of the upper bar of the "0" you have printed there.
    – tofro
    Aug 28, 2023 at 6:52
  • 1
    You don't actually need to use CLEAR to be able to PEEK and POKE into memory if you know what you're doing. $4000 is the screen memory and should be safe to PEEK and POKE, $C000 also is relatively safe as well if you don't have a particularly large BASIC program in memory - ZX Spectrum BASIC fills memory from the bottom up.
    – tofro
    Aug 28, 2023 at 11:52
  • Agreed, however, that you shouldn't normally wildly POKE into Spectrum memory....
    – tofro
    Aug 28, 2023 at 12:01
  • 2
    In an emulator this code works correct. If it does work "correct" in all circumstances, then the emulator has a problem. Otherwise, what you had on the emulator screen wasn't the same as what you had on the screen in the hardware. Aug 28, 2023 at 12:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .