fCPU


Factorio Customizable Processing Unit. Allow to write any logic on low level machine code. The fCPU acts like a programmable microcontroller with a vector coprocessor that supports many useful instructions.

Content
7 hours ago
0.18 - 2.0
12.1K
Logistic network Circuit network

b mem1 channel bug

2 days ago
(updated a day ago)

i used v0.4.50

if i run this program:

clr
mov mem1[33] 415[virtual-signal=signal-H]
mov mem1[35] 250[virtual-signal=signal-N]
mov mem1[36] 750[virtual-signal=signal-O]
mov mem1[37] 10[virtual-signal=signal-B]
mov mem1[38] 10[virtual-signal=signal-A]
mov mem1[40] 40[virtual-signal=signal-P]
mov mem1[41] 40[virtual-signal=signal-R]
mov mem1[42] 80[virtual-signal=signal-Q]
mov mem1[43] 5[virtual-signal=signal-C]
mov mem1[44] 10[virtual-signal=signal-E]
mov mem1[45] 5[virtual-signal=signal-D]
mov mem1[47] 200[virtual-signal=signal-T]
mov mem1[48] 20[virtual-signal=signal-S]
mov mem1[49] 5[virtual-signal=signal-F]
mov mem1[50] 10[virtual-signal=signal-G]
mov mem1[52] 10[virtual-signal=signal-B,quality=uncommon]
mov mem1[53] 10[virtual-signal=signal-A,quality=uncommon]
mov mem1[54] 5[virtual-signal=signal-Z]
mov mem1[55] -1[virtual-signal=signal-no-entry]
mov mem1[56] 28[virtual-signal=signal-H]
mov mem1[58] 10[virtual-signal=signal-N]
mov mem1[59] 30[virtual-signal=signal-O]
mov mem1[61] 10[virtual-signal=signal-P]
mov mem1[62] 10[virtual-signal=signal-R]
mov mem1[63] 20[virtual-signal=signal-Q]
mov mem1[65] 10[virtual-signal=signal-X,quality=uncommon]
mov mem1[66] 6[virtual-signal=signal-W,quality=uncommon]
mov mem1[67] 5[virtual-signal=signal-V,quality=uncommon]
mov mem1[68] -1[virtual-signal=signal-no-entry]
mov mem1[69] 148[virtual-signal=signal-H]
mov mem1[71] 72[virtual-signal=signal-N]
mov mem1[72] 216[virtual-signal=signal-O]
mov mem1[73] 40[virtual-signal=signal-A]
mov mem1[75] 40[virtual-signal=signal-P]
mov mem1[76] 40[virtual-signal=signal-R]
mov mem1[77] 80[virtual-signal=signal-Q]
mov mem1[78] 18[virtual-signal=signal-E,quality=uncommon]
mov mem1[79] 10[virtual-signal=signal-D,quality=uncommon]
mov mem1[80] 6[virtual-signal=signal-C,quality=uncommon]
mov mem1[82] 20[virtual-signal=signal-M,quality=uncommon]
mov mem1[83] 20[virtual-signal=signal-L,quality=uncommon]
mov mem1[84] 4[virtual-signal=signal-I,quality=uncommon]
mov mem1[85] 10[virtual-signal=signal-H,quality=uncommon]
mov mem1[86] 6[virtual-signal=signal-G,quality=uncommon]
mov mem1[87] 2[virtual-signal=signal-F,quality=uncommon]
mov mem1[89] 4[virtual-signal=signal-K,quality=uncommon]
mov mem1[90] 2[virtual-signal=signal-J,quality=uncommon]
mov mem1[91] -1[virtual-signal=signal-no-entry]
mov r3 56
mov r4 mem1@3
mov r3 80
mov r4 mem1@3

the first "mov r4 mem1@3" he should return "H28" in r4 but returns nothing.
the second "mov r4 mem1@3" works, he returned the correct signal "6[virtual-signal=signal-C,quality=uncommon]".
but in the memory channel-view for mem1 the data is shown correct (unfortunally only sometimes).

tenim

a day ago

that program won't be practical, at least for now. you have to use emit instead. which actually works ok. see known behavior: https://gitlab.com/konstg/fcpu/-/issues/11

you might also be interested in: https://gitlab.com/konstg/fcpu/-/issues/12

a day ago

notes from my experiments: these are current as of v0.4.39:
; emit is the way to assign a single cell of a memory bank.
; doesn't work for output, only memN.
; 0 is a valid assignment. it removes the type from GUI.
; previous qty of other types are preserved.
; really the memory bank is a dictionary (associative array or mapping) of type to qty.
; ignore the idea of addressing a memory cell by index number,
; as you would a RAM byte or a contiguous array or vector.
; it doesn't work that way due to internal design of Lua and Factorio.
; signals always get reshuffled, even when they are READ!
; that doesn't seem to apply to inputs. they're stable on read.
; what about scalar outputs? on read? on write?
; what about vector output? on read? on write?

a day ago

Hello,

This is the correct behavior.
When you reassign the same signalid in memory to a different index, the old one becomes free (memory can't hold signalid in different locations).
For example:

; mem1[56] = 28[virtual-signal=signal-H]
mov mem1[56] 28[virtual-signal=signal-H] 
; mem1[69] = 148[virtual-signal=signal-H], mem1[56] = <empty>
mov mem1[69] 148[virtual-signal=signal-H]
; r4 will be empty
mov r4 mem1[56] 

However, with this example, I noticed that the GUI has a bug: fixed memory cells are displayed incorrectly.

a day ago

ah, ok. unfortually than i can´t use mem1-mem4 for storing large control informations and have this put in the code itself. the first link helped me to understand that it behaves like an assiociative array. thanks.
than the only way to safe store multiple signals from the same type is reg1-reg8, right?
or... have an idea. i can store all this signals in mem1-mem4 if i introduce a unique prefix before each number in the signal-values. 32bit -first 12 bits prefix für memory bank nr and index, 20 bits=the actual number. a litte bit-shifting.

a day ago
(updated 22 hours ago)

Issue with a GUI is fixed in v0.4.51

only way to safe store multiple signals from the same type is reg1-reg8, right?

Yes

store all this signals in mem1-mem4 if i introduce a unique prefix before each number

What task are you solving?

a day ago
(updated a day ago)

yeah splitting a quantity into four zones by bit shifting should work. you could stuff several values into 1 if they're not too large. but you're never allowed to have more than one quantity of a given type in a given memory. mem1 is a dictionary, mem2 is a dictionary, mem3 is a dictionary, mem4 is a dictionary.

you're probably going to be disappointed if you keep trying to address memories by index, like mem4[2] or mem4@5. index is going to shuffle around every time you use the memory, making the index useless. rely on type instead.

also be aware you actually have 64 registers, not 8 as the docs say. and those ARE reliably addressable by index. so are your wire inputs.

count how many regs you really have:
clr
mov r1 1[item=pistol]
:next
mov r@1 r1
inc r1
jmp :next
; notice the error message gives the limit.

17 hours ago

What task are you solving?

It is a kind of mall for the production of legendary objects with the aim of using only the minimum resources necessary (without overproduction).
I have legendary iron plates, copper plates, iron ore, plastic, bricks and steel as base materials and can then use them to produce everything
else (later also the SA materials). FCPU controls and monitors the individual machines in all production steps.
Unfortunately, this requires a lot of control commands for the factory. For each item produced (this varies depending on the object tree of the
intermediate products), this averages out to 50 lines of code per product manufactured (e.g. truster, substation or assembly machine 3).
For example, the command "take 30 copper plates for machine x to produce y" is different from "take 30 copper plates for machine y to produce z".
He sends this as commands for requester chests. I have written an Object Pascal programme that generates the complete production code for any
target object with the minimum of needed commands by parsing first the complete material dependence tree. In the end, all control codes for all
target products are in the FCPU, and I then specify the type and number of the desired target product via an external signal (constant combinator).
He then calculates the total amount of materials required and sends the control commands to the factory. This is then timed with waiting for
logistics robots, factories no longer working status etc., and I need a lot of lines of code for this. I'm not sure yet exactly how I'll do
this, but the easiest way is probably to use several FCpus and then activate the right one for a certain product this definition is in his code.

7 hours ago

You also might have external memory bank (constant combinators) for storing data.
And send address signal from fCPU to read from that bank.
When bank read, do the stuff from it's data and switch to next bank.

You may want to use new push/pop/call/ret mnemonics.

5 hours ago

External memory bank is a good idea, and surprisingly easy to design and to use. Let me know if you need a copy of my memory bank design, or if you have your own, or if you're looking forward to designing it.

38 minutes ago

@extermeon
Great that you've integrated the new commands. Really awesome. Thank you.

@cb750mark
Yes, it would be nice to see your memory bank design. I hadn't thought of doing it that way with constant combinators.

New response