Close

Overboard

A project log for Incandescent RAM

Use lightbulbs to store data!

eric-hertzEric Hertz 06/09/2022 at 04:083 Comments

Today I worked out most of how to interface with a Z80... Hah!

It's about 11 relays per data-bit.

Seeing as how I think I might be able to handle 8 bulbs per refresh-circuit (one refresh circuit per data bit), we're coming out a bit behind.

So... Hmmm...

The idea was to have read and write be random-access; completely independent of refresh. There are a couple cases where the refresh and read/write circuits might glitch when run simultaneously... Nothing a couple more relays couldn't fix!

The next idea was a write-circuit which automatically tests whether the bit is fully-written, before releasing the Z80's "Wait" line. Only a couple/few more relays!

Right, these things add up!

...

Scaling back, well... An earlier thought was to use the refresh circuit to also handle reading. That might save a couple/few relays at the cost of an additional pole on the rotary-switch/drum. It also means the data will only be available when the drum gets around to it.

Which, actually, I kinda dig... The idea of hooking this to a Z80 is so utterly ridiculous, but yet, also a *great* demonstration of the Wait signal, which for some reason I'm rather fascinated by.

Writing... Well... I could save a few, maybe several, relays by just using an RC circuit timed a bit longer than it should actually take to write a bit. Heh, why not?

I guess, realistically, since writing a *byte* will almost always contain both ones and zeroes, it'll seldom if ever write all the bits faster than it takes for a bulb to cool.

OTOH, this use of Wait, I'm not as fond of... I'd almost rather write each bit in sequence, as fast as possible, (even if just using separate RC circuits for writing highs and lows), even though it'd be *significantly* slower, because, I guess, I'm fascinated by Wait. This'd demonstrate it better, taking varying amounts of time, depending on the data being written.

Then, of course, there's the question of where do I draw the line between semiconductors and relays? Wait, itself, will almost certainly have to be driven by a bit of automatic logic; a relay can't switch fast enough! But, Even though that'll likely involve a flip-flop (and some glue logic) I'm not sure I want to use e.g. a 7400-series shift-register to load the bits in/out.

I dunno, we'll see if this actually goes anywhere. It didn't *start* with thinking to interface with a Z80... it got there when I realized my Write/Verify circuit would take differing amounts of time, and would go well into that Wait pin. 

That inkling was already there, though, when I realized the Read circuit has two separate outputs, two separate relays, for high vs low. Thus, its data output is guaranteed valid when one of those relays is switched-on. It inherently tells you (or the next circuit) when its data is valid, when the operation is complete.

I kinda dig that. Especially since its speed may vary depending on things like ambient temperature, or even the shapes of the contacts in the rotary-switch/"drum." Which, actually, are not all identical. Some are skinnier due to the trace connecting the pole to its solder-tab. Those skinnier contacts will likely result in bulbs that average just a slight bit cooler-when-hot than the others. Thus their resistances will be slightly lower, which would make for lower voltages on the output of the voltage divider, making for more slowly-transitioning relays... And, then, leaving even less time, while sliding across the already skinny drum contact, to do the actual reheating. Thus, some bits will inherently take longer to read than others, which, again, I kinda dig the idea of a system that gets it out there as fast as it can, and inherently "clocks" the next process when it's ready (deactivating Wait).

I'm not certain, by any means, but I think 16 bulbs per refresh circuit is probably pretty close to the limit, based on how much time they'd need to reheat. I was thinking maybe 8, for this project. Then 8 of those in parallel for 8 bytes of "RAM."

The refresh circuit only requires two relays, so 16 total. But, then back to read/write... And shifting vs. parallel-loading, and whether it's actually *more* relays to cycle the same read/write circuit across 8 data bits, rather than just make 8 R/W circuits... Oh, and whether the additional latching circuitry necessitated by waiting for the drum to roll around to the requested data might mean even more relays than true random-access... Heh, now I'm a bit overwhelmed by all the options.

Oh, also, the other day I think I came up with a way to "step" through the "drum" positions using a DC motor and a couple relays. I'm not sure how I feel about that. On the one hand it means somewhat more reliable timing than the switch contacts alone provide, especially with different switches, like one whose dead-space vs contact-area is quite large. On the other hand it means starting and stopping a motor really fast and really often... I dunno, at some point it would seem hard on it. OTOH, it would be an interesting thing to see.

The trick is to *stop* the motor when it makes contact, so it can't overshoot. Thus, when the switch contact is made, it powers a relay which shorts the motor winding. But, then, how to get it to start again? Won't it just detect the contact it's already on and stop immediately? Two such relays, alternately-connected to alternate switch positions. When on an even contact, tell it to go until it sees an odd contact, and vice-versa.

I suppose, then, it'd be rather easy to control the speed using an RC circuit or two. Could probably pretty easily control the duration it stays on each contact separately from how quickly it moves between them. And, this system might also lend itself to fixing the Do-Refresh timing problem... Contact is made before the braking relay kicks-in. Another set of contacts on that relay would assure DoRefresh doesn't occur until *after* the bulb is switched-in.

Of course, now this means trying to figure out how to couple a motor to the switch. Heh.

Anyhow, I guess now I'm a bit overwhelmed. It seemed to be going so smoothly when I was working out the details on the TooManyRelays path... Now it seems like there are too many paths to consider, and none of them nearly as functionally-ideal. We'll see where it goes. Maybe "functionally ideal" isn't about speed, nor maybe even about considering all glitch-cases... This *is*, after all, a rather ridiculous endeavor.

...

LOL, duh....

Lessay I was thinking about how to load 8 bits in, one-by-one, onto the 8-bit databus....

Lessay we have a refresh-circuit which just happens to go through 8 bits, in sequence, first reading them, then latching the values read to the appropriate voltage rail, in order to refresh them... Hmm...

So, obviously, we need a shift-register to read out the 8 bits from 8 separate refresh circuits all accessing their associated bulb in that same row... right?

LOL, wth was I thinking? The friggin drum *is* a shift-register, dumbass!

...

Erm, wait... WUT?

Why was I thinking about loading the bits serially, rather than in parallel? In an attempt to reduce the relay-count. But using the drum's serial nature does nothing for that... because accessing the next byte, later, in the next column, rather'n row, means we still need another RW circuit on that column.

Ooof, see what I mean? Too many paths to consider, overwhelmed.

...

Sheesh... Day two, now, of overboard/overwhelmed. Nothing really came of this day, despite my efforts. Which is to say three pages devoted to what turned out to be utter jibberish. Seriously, I thought, for HOURS today, knowing FAR better for most my life, I might get away with putting individual Diode-ROM Program memory bytes on separate address lines, rather than needing to decode the address bits? Oh the idea was great! Imagine, A15 is a simple chip-select for RAM vs ROM. Then the incandescent RAM's 8 bytes can be selected by A0-A7, individually... Aside from A15, no address-decoding necessary!

OK, actually that's not a horrible idea.

But then I was convinced I could do the same with program memory... For Hours.

The first hurdle was what to do about addresses between the 2^n's... Simple, just tie the data bus to NOP through resistors. So... yahknow, the higher instructions would take longer to reach, big whoop, we've got a machine that takes two seconds to write a zero to RAM... A few thousand NOPs is nothing!

So, I got pretty far in before realizing that it'll only work with one-byte instructions... This AFTER a bit of excitement at the prospect that maybe I could find a couple sequential addresses accessed with this no-decoding-scheme that would put the first instruction op-code in ROM, and the second in RAM, for self-modifying code... Yahknow, right between A15's being low, then going high. No... I can't math today, I won't even try, but basically 1000 follows 0111, NOT 0100.

Seriously, I was convinced-enough as to think of the possibilities for some time.

Then... (did I mention this day started with my spilling my coffee all over the candy under the cashier's counter?)

Right... So, single-byte instructions, *except* for the first, at A0=1, because A1=1 immediately follows, so I could put a two-byte instruction there... This could actually be usable! Diodes and a bunch of DIP switches. For those little quick-experiments that don't warrant digging out the computer and flash-programmer... Yahknow, like this groovy LED light-bar I've been wanting to try out that has 8 LEDs embedded in the same epoxy, which I think could look almost fluid if animated... This DIP-Switch-programmable microcontroller could be a handy thing to keep next to solderless breadboards...

So then I looked up all the 1-byte instructions... And, went so far as to figure out some hackery, like since there's no conditional-jump use conditional-return, instead, and since there is no stack  and most addresses will return NOP=0x00, we essentially have a jump to 0x00, which of course is a NOP, which makes it a jump to 0x01... Hey, this thing could actually work... And then something about reset vectors, which I only vaguely understand, but might work similarly... And a lot of things with HL, so I could use that first two-byte instruction to load HL... I mean, this could actually work, ish.

Right... Hours later... Wait, the count doesn't go from A0 then ... wel, sheesh, whatever I WAS thinking for so long is so ridiculous I can't even figure out how to word it, now...

Right, so the boot address is 0, that'll not select any of the diode-switches, so NOP. The next address is A0=1, selecting the first set of switches. The next is A1=1, the second set of switches. The next is irrelevant, a bunch of NOPs until A2=1.... Right? WTH was I thinking?! No. After A1=1, then A1=1 AND A0=1, selecting TWO instructions, simultaneously. DUH.

Ugh, the whole day was like this. 

2AM, writing this, after many more hours feeling utterly stupid. MAYBE something can come of it...

I mean, it's not *that* hard to throw in an address demuxer. A really simple microcontroller like that, with dip-switch instructions, might be quite a handy breadboard prototyping tool...

And, the Incandescent RAM *can* be wired-up that way, since it doesn't have to be accessed sequentially.

...

Heck, I could even disable readback to the processor, feed it NOPS, and use it as a counter/sequencer to address the DIP switches to do other things like initialize an LCD display... Basically use it as a multibit counter. LOL, Or I could just go back to my roots in TTL. Yeah, a binary counter might be handy to have around.

Heh, what a day.

....

Day 3

I wonder what two-byte instructions would actually be useful when the second byte is always zero... hmmm... Or three-byters that have two zeroes? LOL Did I not just determine that there's no need for this challenge because it flat-out won't work? Sheesh, brain! Stop!

...

In and Out are now available! The rest are mostly useless, math with 0. Jump relative (conditional!) 0... hmm... loading to/from address 0, loading 0 into registers and hl... Not at all useless, but just barely.

Unless, again, you consider the fact that This System Won't Work. Address-decoding is Necessary! So, unless you just happen to have a bunch of 8-in ANDs and inverters, or something, rather than a single demux, this whole venture is utterly ridiculous! Brain. Get Off It!

Oooh, but wait... What if... NO!

...

Actually....

Say I do get a demux in the picture, is it the 74154 4-to-16 demux? Instead of placing it at A0-A3, place it at A2-A5. Then a 16-byte diode/DIP-Switch ROM is a possibility, which is 1 more than the other (impossible) method, anyhow. And makes for either single-byte instructions followed by three NOPs AND these two/three-byte instructions where the two following bytes are zero... It could actually be useful. Otherwise, well, multibyte instructions would eat up those 16 bytes VERY quickly... OTOH, it might take several single-byte instructions to accomplish the same effects as many useful multibyte instructions... So, I guess the question is whether this would be a worthy compromise.

I don't even recall under which project I wrote a log-entry about my idea for a homebrew computer modular build-up process... (Found It: https://hackaday.io/project/167010-todays-assorted-project-ramble-grab-bag/log/205016-homebrew-computers-transistors-and-surely-more/discussion-175242) Wherein the pull-resistor NOPulator is the first step, just to see the address bus counting, followed by a tiny diode-ROM program (three bytes, maybe, to jump back to 0), followed by a larger dip-switch-diode-ROM... This might lend itself to that. Therein, maybe the demux's inputs to address lines might be jumper-selectable. Hmmm...

Goofy, anyhow.

Discussions

Dr. Cockroach wrote 06/11/2022 at 10:02 point

Don't you just love it. Grasp onto a cool idea like Incandescent RAM and then watch all the rabbit holes start to add up faster than your bits ;-) But in truth there is a whole lot of discovery and learning going on here :-)

  Are you sure? yes | no

Eric Hertz wrote 06/11/2022 at 17:52 point

LOL, like learning 15 years after a ten year career in this field and 15 years of off-n-on exercisizing in the field that I can so easily forget something so fundamental as binary? Yikes!

But, actually, rereading, it occurs to me maybe I could figure out how to avr-gcc and avrdude from my phone for those quick experiments. I dunno, the "blackbox" approach to test-equipment kinda bugs me; months later I'll've forgotten what it was set up to do! Needs a screen just to show what code it's running... 

Sheesh! Now that I think about it, actually, this is *exactly* why I started #Vintage Z80 palmtop compy hackery (TI-86) ... A sorta microcontroller I could program on the microcontroller, itself.

Maybe I need to throw a bus-breakout header on there. 

I got a little carried-away with that project in trying to keep my mods as easy and accessible as possible so others could use them, too... Like the UART code, which would've been a thousand times easier if I just soldered-up a counter/timer chip, or even a friggin UART. Heh. Or maybe even just replaced the RC oscillator with a crystal.

Heh. Guess I lost sight of my original goal with that one, too!

So, what've I learned? Rabbit holes... something about Rabbit Holes...

  Are you sure? yes | no

Eric Hertz wrote 06/11/2022 at 18:12 point

LOL, sheesh... Seriously, that was SO the original goal with the TI-86... I'd also, though, been quite hesitant to *do* much to/with it because I've done so much to/with it, I don't want to lose...

Friggin' ironic. The whole point was these things are *abundant*. I'm remedying this, right now.

  Are you sure? yes | no