However, I had a LOT of fun making it and wanted to create better versions. Therefore, I started working on a clocked memory module. The idea was that the module would have two separate input wires, one for the clock signal and other for data. Whenever the clock wire has any signal, the module should load whatever signals are present on the data wire and output them at its output until the next clock signal changes its memory.
TLDR:
Single Address (save when S is non-zero)
Addressable with address x (change conditions to S!=x in 1st combinator and S=x in 2nd)
I started with a decider combinator feeding into itself when a signal S=0. This way, I can control when this combinator feeds itself.
To prevent a continuous signal from causing an infinite loop (loop that increments till the signal is zero), I had to stop the above combinator from feeding itself when there was a signal at the input.
For this, I used another decider combinator that allows data to pass through only when S!=0 (S is not 0)
This way, I could use the S signal as a flag for when to let data into the memory. Just like a clock signal...!
When S=1 data is allowed to flow through the 2nd combinator and the 1st one doesn't loop due to its configuration.
When S=0 data is not allowed to flow through and never interferes with the memory combinator's loop.
Since I use the S signal to control the working of this module, this signal should never be a part of the input data. It should instead always be separate from the data line, i.e. on its own wire.
Notice that now even the S signal can enter the memory loop. In fact, it is entered twice, once directly from the clock signal wire and then by passing through the 2nd combinator. This causes the memory loop to never start in the 1st combinator since S=0 is not satisfied even when the S signal in the clock wire is removed.
To solve this, I simply added an arithmetic combinator to cancel the S signal obtained from the 2nd combinator.
This 3rd combinator serves only to remove all S values from both the clock and data input signals.
Now by connecting a "data" source on the 2nd combinator, I can use the S signal to save this into the memory.
When the S signal is non-zero, this module saves whatever is on the data wire (here green wire from constant combinator). This means that to clear the memory, I can simply pass nothing on the data wire while the clock signal S has a non-zero value.
Making this Addressable
Notice that the "data" is allowed to enter the module when the S signal is non-zero and it is saved in the loop when S=0. This means that if we change the two conditions for our 1st and 2nd combinators to only allow specific values of S, we can make this addressable.
This can be done very simply. Here I show this by using 10 as the only S value that the module accepts data for :-
The final memory cell looks as such