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
1 CLS : PRINT
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:
- 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).
- 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.