13

Many moons ago when I owned a ZX80, I remember (or possibly mis-remember) seeing a simple way to double the RAM to 2K by simply piggy-backing two extra 1Kx4 chips on top of the existing two (with pin-to-pin solder), for all pins bar the chip select (CS).

CS on the new piggy-backed chips would be "bent out" and sourced from a small circuit which would only be set for the 1K-2K range.

However, from circuit diagrams found on Grant Searle's excellent pages, it looks like current CS is set by taking the NAND of [MREQ']' and A14', meaning every address in the 16-32K and 48-64K ranges selects those original RAM chips (with 0-16K and 32-48K presumably being reserved for ROM):

enter image description here enter image description here

Given only the lower ten address lines are delivered to the RAM chips, this has the effect of duplicating the 1K RAM at every 1K boundary in those ranges (so the same data would exist at 4000, 4400, 4800, ... 7C00, C000, C400, ... FC00)(1).

So my question starts with: how did the 16K RAM expansion handle this without cutting the CS feeds (the actual solder tracks) to the existing RAM chips? Having both the internal and external RAM pushing bits on to the data bus for certain addresses would surely result in much hilarity :-)

The RAM CS signal is sent to the expansion port but I can't figure out how, when a memory board was plugged in, it would somehow prevent the internal RAM from responding to some addresses (or all addresses if it was replaced by the expansion RAM rather than augmented by it).

My original thought on how to do it with the piggy back method would be to take the current RAM CS and combine that with A10 so that it only selected the new RAM for alternate 1K regions of the RAM areas.

But that means I would have to similarly modify the CS for the old RAM so that it didn't select on those same regions. In other words, the current RAM CS would have to be processed something like this (apologies for the "graphics"):

RAM CS ──┬─────────┐
         │       (and) ── CS[NEW]
   A10 ─[│]───┬────┘
         │  (not)
         │    └────┐
         │       (and) ── CS[OLD]
         └─────────┘

That would require cutting tracks on the motherboard to change how the old RAM was selected because, currently, RAM CS feeds directly into CS[OLD].

So maybe there's another way if the RAM pack can do it. Though, if it requires replacing on-board RAM then, obviously, piggy-backing 1K will not be enough as that would simply replace the current 1K with a different 1K.

So the second (and final) part of my question is: how feasible is this piggy back approach, either with:

  • trying to figure out how to piggy-back a couple of 2Kx4 chips to replace onboard memory (so I'd need a separate A10 line to the new chips and a way to disable existing RAM); or
  • using the "cut the trace" method to augment the existing 1K with another 1K?

(1) It's fun figuring out the tricks used to keep the costs down for this and other hardware of the era. Though I still think that the ZX80 "execute the display file" and Woz's brilliant Apple II RWTS routines put a lot of other things to shame :-)

12
  • Too little for an actual answer: /RAMCS can be overridden to disable the built-in RAM. Aug 14, 2023 at 6:13
  • I suppose R19 makes it possible to give the RAM C.S. signal whatever level you want without damaging the circuits on the other side of it. Don't have the current figures in my head, so I can't say for sure.
    – UncleBod
    Aug 14, 2023 at 7:02
  • Why would the external RAM pack need to disable the internal RAM? It would have exactly the same contents for the range of addresses where they overlap, and so would always put the same data on the bus. Aug 14, 2023 at 7:48
  • 1
    @Lorraine, The internal 1K treats every address as if a14-a10 were all zero, effectively duplicating its memory throughout the address space.. That means it will not agree with the external RAM. Ask to read memory location 1029, the external pack will give you 1029 while internal memory will give you 1029-1024. That's likely to be two different values.
    – paxdiablo
    Aug 14, 2023 at 8:04
  • 1
    This same hack was used to add another bit of video memory to the TRS-80 model 1, so that it could support lowercase. Aug 14, 2023 at 15:30

2 Answers 2

8

Prelude

Given only the lower ten address lines are delivered to the RAM chips, this has the effect of duplicating the 1K RAM at every 1K boundary in those ranges

Yes, that's exactly as the ZX80 decoding works. It only uses A14 to distinguish between RAM and ROM.

  • A14=0 -> ROM
  • A14=1 -> RAM

That's why the original 4 KiB ROM shows up 4 times at 0000h, 1000h, 2000h and 4000h (*1) and the RAM 16 times from 4000h to 7C00h. And that again doubled for the upper 32 KiB (*2).

And the same of course for the (today mostly forgotten) 3K RAM Pack which made the RAM repeat at 4/5/6/7000h.

Question Part 1

So my question starts with: how did the 16K RAM expansion handle this without cutting the CS feeds (the actual solder tracks) to the existing RAM chips?

The 16 KiB simply disables the internal RAM by forcing it to +5V as seen on its schematics (half way down on the left side):

ZX RAM-Pack Schematics

That way it doesn't matter what that NAND outputs, it will always be as high as it can be. Ofc, this means the NAND will draw some power, but who cares, the ZX series is made to be cheap, not fine art.

Question Part 2

My original thought [...] would be to take the current RAM CS and combine that with A10 so that it only selected the new RAM for alternate 1K regions of the RAM areas.

Jup, that's the basic point of all expansions: They need to add the lines A10..A13, depending on how much RAM is added.

But that means I would have to similarly modify the CS for the old RAM so that it didn't select on the same regions.

Yes

That would require cutting tracks on the motherboard to change how the old RAM was selected.

No - why not using the same 'trick' as the RAM pack? Pull /RAMCS high whenever the added RAM is to respond.

how feasible is this piggy back approach,

It world, although gets more and more complicated with increased number of chips. Adding a second KiB is fine (and quite a relief) but another two will already make a huge tower - and need more complicated decoding.

At that point it may be simply better to unsolder the existing RAM and use the holes just to grab the signals to feed a little daughter board holding all chips

Which may be quite small a 2Kix8 chip (6116) - or to get fancy, a single 8Kix8 6264. In either case no additional logic is needed. /RAMCS is still /CS to the (new) RAM chip. Ony A10 (and above) must be wired from some other source (*3). Kinda like the ZX81 did for the Timex 1000 version (*4).

or use the "cut the trace" method to augment the existing 1K with another 1K?

Or just cut/unsolder the CS of both chips and have them connect to your new decoding - essentially having all CS going sideways.

As mentioned, that type of modification has been done a lot. I remember one guy doing that for 8 KiB on a ZX81. That is creating two stacks of eight 2114 each, having 8 CS wires going from each stack toward the output of a 74138 decoder which in turn was fed by A10..A12 plus /RAMCS as enable (signal taken from the original /CS pin at one RAM). Looked absolutely Mad-Max style but worked fine.


And one more:

trying to figure out how to piggy-back a couple of 2Kx4 chips to replace onboard memory

There are no (mainstream) 2 Ki by 4 chips. RAM size grows quadratic, so the next size was 4 Ki by 4, like 6168. But they never made big sales, as he same chip size but organized as 2 Ki by 8, the well known 6116, made it - including for the TS1000 :))

At the time larger memories would be made using DRAM, so only special cases (*6) and embedded/low power used SRAM. So a 6116 can deliver 2 KiB in a single package saving at least 10 holes drilled, while two can do so for 4 KiB on par with two 6168.


Side note: IIRC the internal RAM does, unlike the RAM-PACK as well perform a read during /REFRESH - that should enable to use the internal expansion as well for highres graphics (not telling that there can be a lot :))


*1 - The later 8 KiB ROM did so twice at 0000h and 2000h - much like it did on the ZX81.

*2 - The RAM copy being used for video generation - so A14=A15=1 equals video access.

*3 - I have seen modified ZX81 with an 8 KiB RAM simply glued upside down onto the board and all pins connected by wires to the original 2114 holes and A10..A12 on the CPU. As brutal as it is simple.

*4 - Always useful to keep in mind that the ZX81 is just a cost reduced ZX80.

*5 - Like for the VIC-20 redesign.

4
  • "two stacks of eight 2114 each"? How the heck did that even fit inside the case? Or was a hole made in the top where it could stick out? Regardless, appreciate the answer. ... Never mind, kept reading and saw the "Looked absolutely Mad-Max style" :-)
    – paxdiablo
    Aug 15, 2023 at 3:19
  • 1
    @paxdiablo exactly like that Ford Falcon from Mad Max.
    – Raffzahn
    Aug 15, 2023 at 11:40
  • In your text about tying RAMCS to 5v, you mention middle of the right side of the schematic. Should that be middle of the left side?
    – paxdiablo
    Aug 16, 2023 at 22:17
  • 1
    @paxdiablo Drats. Yes. I'm sorry. Will change it.
    – Raffzahn
    Aug 16, 2023 at 23:38
3

A small addition to Raffazahn's excellent answer: take a look at the circuit diagram for the ZX80 you linked. The logic for generating the RAM CS line is here:

ZX80 RAM CS logic

Note, specifically, the existance of R19, a 2K2 resistor that has no obvious purpose in this circuit. Its actual purpose is to allow another module (i.e. a RAM expansion pack) to connect between the resistor and the RAM chips and take over driving the line. Similar resistors exist on chip select lines on a lot of 80s era computers, specifically so that their behaviour could be customised by add-on hardware. Unfortunately, the ROM chip select lines on the ZX80 weren't designed this way, so the ROM can't be banked out by external hardware, meaning you couldn't make a 64K expansion for it, but if they had been this would have been achievable.

2
  • Yes, that's a protection resistor. It restricts in case of an external pull to 5V the current toward the NAND to less than 2 mA, which is way below the allowed sink current.
    – Raffzahn
    Aug 16, 2023 at 2:46
  • Unfortunate about the same trick not being available for ROM, that would have allowed some nice trickery, like fixing bugs in the ROM, having much more functionality in ROM, or turning the ZX80 into a Forth-driven Jupiter Ace :-)
    – paxdiablo
    Aug 17, 2023 at 0:22

You must log in to answer this question.

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