[HN Gopher] LFSR CPU Running Forth
       ___________________________________________________________________
        
       LFSR CPU Running Forth
        
       Author : izabera
       Score  : 68 points
       Date   : 2025-06-02 03:35 UTC (19 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | kragen wrote:
       | This is pretty cool. There were some LFSR-PC CPUs back in the 70s
       | such as the TMS 1000 used in the Speak&Spell
       | https://github.com/mikeakohn/tms1000_fpga (its Data Manual omits
       | mention of this, but the Programmer's Reference Manual does
       | mention it
       | https://ia800306.us.archive.org/27/items/bitsavers_tiTMS1000...),
       | and of course the Atari 2600 TIA raster generator is famous for
       | using an LFSR counter for horizontal position. Ken Shirriff has
       | also documented the use of an LFSR counter for tone generation in
       | the UM66T greeting-card music chip
       | http://www.righto.com/2021/12/reverse-engineering-tiny-1980s...
       | and for Pentium self-test circuitry
       | http://www.righto.com/2025/01/pentium-carry-lookahead-revers...
       | and for DTMF tone generation.
       | 
       | It occurred to me recently that an LFSR-pc CPU could avoid having
       | an address field in its conditional jump instructions, instead
       | doing something like complementing a PC bit. There have been
       | conventional counter-based CPUs that did something like this:
       | Data General's NOVA and HP's RPN calculators had conditional-skip
       | instructions which would skip over the next instruction without
       | executing it if the condition was false. But it was usually a
       | jump instruction, so it didn't really save you space. (The TMS
       | 1000's conditionals also worked this way, but could _only_ skip
       | branch and call instructions.)
       | 
       | By contrast, in an LFSR, complementing a bit or incrementing the
       | value takes you potentially far away in the address sequence. The
       | assembler might have to insert NOPs to resolve the occasional
       | collision.
       | 
       | The TMS 1000 program counter had an additional twist: it was only
       | 6 bits, but to enable programs of more than 64 instructions,
       | there were multiple 64-byte "pages" of ROM. The page address
       | register was potentially updated on branches, calls, and returns,
       | but not for normal program sequencing. I'm not sure if this
       | actually saved any transistors, but it meant that normal branch
       | instructions only needed a 6-bit field. An additional "load page
       | buffer" instruction was needed for far jumps and calls, and the
       | page buffer register remained loaded with the return page until
       | the return instruction. (Subroutine calls within subroutines were
       | not supported.)
       | 
       | https://electronics.stackexchange.com/questions/186762/first...
       | claims that the TMS 1000 had 8000 transistors, which seems really
       | inefficient compared to things like the 4004 and the MuP21.
        
         | jecel wrote:
         | Didn't the TMS 1000 include the processor, i/o, ROM and RAM?
         | All that in 8K transistors seems frugal.
        
           | kragen wrote:
           | That's a good point. It's more like an 8051 than a 4004, and
           | the 8051 was 50k transistors.
        
       | howerj wrote:
       | I had a lot of fun writing this and it is great to see this
       | submitted here, I just did it to see what was possible. It is an
       | incredibly niche processor with little practical use. If you have
       | any questions let me know.
       | 
       | I have also started contracting in the UK and I'm looking for
       | work, details are in my profile.
        
         | kragen wrote:
         | You may be interested in #forth on Libera, though it's unlikely
         | to lead to work.
        
           | sph wrote:
           | It's unlikely to find paid Forth work, though I hope there is
           | still someone hiring engineers that write Forths and LFSR
           | CPUs in their spare time. One will find they are quite
           | versatile and eager to learn :)
        
             | howerj wrote:
             | Ah yeah, I'm not looking for Forth work, it would be nice,
             | but not likely. Just C/C#/.Net/Linux and Embedded work.
        
         | alexisread wrote:
         | Nothing involving forth (only Java really) where I'm working,
         | but I wanted to send some appreciation for Embed forth (meta-
         | compiler), the documentation is particularly good :)
        
       | artemonster wrote:
       | I have used the same LFSR-PC trick for my relay CPU:
       | 
       | https://github.com/artemonster/relay-cpu
       | 
       | Instead of having 24 relays to have a 12bit incrementer (a full
       | adder requires 4 DPDT relays per bit or 2 quad relays) I only
       | have 3 relays for 3 XORs :)
        
       | tyrellj wrote:
       | I got lost in the weeds following links for a bit. Had not heard
       | of LFSR before, which I think is odd, and then onto some other
       | things like Subleq and OISC. I've at least seen other OISCs
       | before, it might have even come up on hn around x86 mov, I'm not
       | sure. I really regret not taking more hardware/electronics
       | courses in college.
        
       | jsd1982 wrote:
       | Wouldn't this make it somewhat more challenging for
       | assemblers/compilers to emit branch instructions with target PC
       | offsets?
       | 
       | For instance, the offset of an instruction two instructions away
       | would be calculated as `lfsr(lfsr(pc))` (off-by-one bugs
       | notwithstanding), right?
        
         | anthk wrote:
         | If the PC offsets are non-repeating, you would just create a
         | table from a known start. Kinda like Ouruborus, or the Humming
         | distance between vertexes in a cube without repeating.
        
       ___________________________________________________________________
       (page generated 2025-06-02 23:01 UTC)