Known issues/2.0.16: Difference between revisions

From Turing Complete
(→‎Wire Spaghetti: Second RAM workaround from https://discord.com/channels/828292123936948244/893929557072162827/1363453331275776140)
(→‎Wire Spaghetti: Added Bottom panel shows nop)
 
(17 intermediate revisions by 8 users not shown)
Line 2: Line 2:
{{Early-access-version|2|0.16|apha}}
{{Early-access-version|2|0.16|apha}}


A number of levels in version are known to be broken, and require some workarounds to complete. Some of thes issues affect multiple levels, I only give the first level you are likely to come across them.
A number of levels in version are known to be broken, and require some workarounds to complete. Some of these issues affect multiple levels, I only give the first level you are likely to come across them.


== Unofficial partial fixes ==
== Unofficial partial fixes ==
Line 24: Line 24:
</pre>
</pre>


Some people report that the bit-width tool appears simply by going to the Sandbox then component factory.
If your game is running, restart the game to ensure the changes take effect.
 
Some people report that the bit-width tool appears simply by going to the Sandbox then component factory. This works only if you first hoover the cursor over wire colors tool in a way that color panel stays open when the cursor is moved away and than click on Sandbox button.


If that does not work you can copy-paste 16-bit components from the sandbox.
If that does not work you can copy-paste 16-bit components from the sandbox.
The level log mentions "like in the register level", disregard that as that level has been removed, and this text not yet been updated to match.


== Wire Spaghetti ==
== Wire Spaghetti ==
Line 34: Line 38:
Various issues with RAM in Wire Spaghetti and following levels.
Various issues with RAM in Wire Spaghetti and following levels.


These stem from the lack of API in <code>text.si</code> to identify which RAM block is the program and which is the register file.
These stem from the lack of API in <code>test.si</code> to identify which RAM block is the program and which is the register file.
 
Before attempting the following workarounds, enable the bit-width tool by following the steps in the [[Known issues/2.0.16#Symphony Counter]] section above to modify your <code>levels.txt</code> file, if you have not done so already.  The bit-width tool will then be displayed below the wire comment tool and is required to set the bit size of the ram blocks during the following steps.  You can see how wide existing RAM is by the width of the orange highlight.


'''WORKAROUND A''':
'''WORKAROUND A''':
# Delete the RAM for both register file and program.
# Set the bit width tool to 16, if you don't have it, see above or move onto B below.
# Place a 16-bit RAM for the register file (the size is hidden).
# Set the bit width tool to 32.
# Place a 32-bit RAM (again size is hidden) for the program.
# These steps should be taken in order. This might take several attempts, for reasons that are unclear to me.
'''WORKAROUND B''':
# Delete the RAM for both register file and program.
# Copy-paste a 16-bit RAM from sandbox for the register file, then
# Copy-paste a 16-bit RAM from sandbox for the register file, then
# Copy-paste a 32-bit RAM from sandbox for the program.
# Copy-paste a 32-bit RAM from sandbox for the program.
# These steps should be taken in order. This might take several attempts, for reasons that are unclear to me.
# These steps should be taken in order. This might take several attempts, for reasons that are unclear to me.


'''WORKAROUND B''':
'''WORKAROUND C''':
 
If the above doesn't work, you can also try this, which has been reported to help.
If the above doesn't work, you can also try this, which has been reported to help.
# Remove the program counter (PC) from the level;
# Remove the program counter (PC) from the level;
Line 51: Line 67:


The level log for Wire Spaghetti states:
The level log for Wire Spaghetti states:
3. Click "Edit link components" on the program component and then "Add register file". (do not connect the zr register)
3. Click "Edit link components" on the program component and then "Add register file". (do not connect the <code>zr</code> register)


This is now wrong, zr should be linked, as part of the register file.
This is now wrong, <code>zr</code> should be linked, as part of the register file.
 
=== Bottom panel shows nop ===
 
If the bottom panel shows <code>nop (does nothing)</code> then first make sure the load port connected to the program counter is the lowest (nearest to the RAM). If it is see above.


=== RAM is byte addressed ===
=== RAM is byte addressed ===
Line 67: Line 87:
== Integrating ALU ==
== Integrating ALU ==


The ALU you previous built has a multipy instruction. The tests for Integrating ALU assume mul returns zero.
The ALU you previous built has a multiply instruction. The tests for Integrating ALU assume <code>mul</code> returns zero.


'''WORKAROUND''': Delete or otherwise disable the multiply componet inside the ALU custom component.
'''WORKAROUND''': Delete or otherwise disable the multiply component inside the ALU custom component.


== RAM ==
== RAM ==
Line 75: Line 95:
=== The level log is incomplete. ===
=== The level log is incomplete. ===


There are 4 new instructions:
There are 4 new instructions, not the 2 listed in the level log:
* <code>store_16</code>
* <code>0: load_8</code>
* <code>load_16</code>
* <code>1: store_8</code>
* <code>store_8</code>
* <code>2: load_16</code>
* <code>load_8</code>
* <code>3: store_16</code>


The level log incorrectly states put the store port at the top, they should (for this level) be at the bottom.
The level log incorrectly states put the store port at the top, the 2 store ports should (for this level) be at the bottom, see below for my recommended ordering.


'''WORKAROUND''':
'''WORKAROUND''':
Add to the existing program block from bottom to top:
From bottom to top the ports attached to the program RAM block should be:
# a 16-bit store port, then
# a new 16-bit store port, then
# an 8-bit store.
# a new 8-bit store port.
# Move the existing 32 bit load port above the store ports, followed by
# The existing 32 bit load port (used for instructions) should be moved above the store ports, then
# a 16-bit load port, and
# a new 16-bit load port, and finally,
# an 8-bit load port.
# at the top, a new 8-bit load port.
The level log also incorrectly states that the 'load' and 'store' instructions should use "argument B" as address parameter. However, for this level that is not relevant. Instead you should use the immediate value as an address to store and load data in the program RAM.
 
As a further clarification, the 'store' instruction should fetch data from the register file at the address determined by "argument A" and store that in program RAM. The level log makes it seem as though you should store the value of "argument A" itself in program RAM, but that is not the case.
 
== SSD ==
 
=== The level log is incomplete. ===
Similar to the RAM level, there are more instructions than shown in the level log, 4 new instructions are added, all instructions are:
 
* <code>0: load_8</code>
* <code>1: store_8</code>
* <code>2: load_16</code>
* <code>3: store_16</code>
* <code>4: pload_8</code>
* <code>5: pstore_8</code>
* <code>6: pload_16</code>
* <code>7: pstore_16</code>
 
=== Memory should contain value 0, at address 3, not 31. ===
When placing the SSD component in your symphony architecture, you might get this error. This is again a problem with the <code>test.si</code> file where it mistakes your program RAM with your register RAM. To fix this, try using the workarounds described in the [[Known issues/2.0.16#Wire Spaghetti]] section. Similarly, if you get the error "Set RAM size to 65536.", then that could also indicate the same problem.


== Instruction aliases ==
== Instruction aliases ==
Line 95: Line 135:
=== Level fails to compile due to wrong meta.txt ===
=== Level fails to compile due to wrong meta.txt ===


Edit <code>Turing Complete\campaign\symphony_9_aliases\meta.txt</code> and delete the last 4 lines of default_assembly, so that the section reads
Edit <code>Turing Complete\campaign\symphony_9_aliases\meta.txt</code> (found in the game's install folder, not your save files) and delete the last 4 lines of default_assembly, so that the section reads


<pre>default_assembly = `
<pre>default_assembly = `
Line 147: Line 187:
s/(^|  )([01][01])0/$10$2/g
s/(^|  )([01][01])0/$10$2/g
</pre>
</pre>
=== Wrong assembly instructions ===
The assembly instructions for various levels is incorrect, some instructions that are bugged include, but are not limited to:
* Store and load instructions (including pload and pstore)
* Move, neg, and not instructions
* Push and pop instructions
* Call and return instructions
Several of these have the wrong Mode, wrong OPcode, or are simply outdated. Below shows the correct instructions for these functions. You can either change them in game or in the meta.txt file associated with the level.<syntaxhighlight lang="text">
load8 %dest(register), %address(register)
01100000 dddd0000 0000aaaa 00000000
Loads %address from RAM and stores it to %dest
store8 %address(register), %value(register)
01100001 0000vvvv 0000aaaa 00000000
Store %value to %address in RAM
load_8 %dest(register), [%address(immediate)]
01110000 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from RAM and stores it to %dest
store_8 [%address(immediate)], %value(register)
01110001 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in RAM
load16 %dest(register), %address(register)
01100010 dddd0000 0000aaaa 00000000
Loads %address from RAM and stores it to %dest
store16 %address(register), %value(register)
01100011 0000vvvv 0000aaaa 00000000
Store %value to %address in RAM
load_16 %dest(register), [%address(immediate)]
01110010 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from RAM and stores it to %dest
store_16 [%address(immediate)], %value(register)
01110011 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in RAM
pload8 %dest(register), %address(register)
01100100 dddd0000 0000aaaa 00000000
Loads %address from SSD and stores it to %dest
pstore8 %address(register), %value(register)
01100101 0000vvvv 0000aaaa 00000000
Store %value to %address in SSD
pload_8 %dest(register), [%address(immediate)]
01110100 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from SSD and stores it to %dest
pstore_8 [%address(immediate)], %value(register)
01110101 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in SSD
pload16 %dest(register), %address(register)
01100110 dddd0000 0000aaaa 00000000
Loads %address from SSD and stores it to %dest
pstore16 %address(register), %value(register)
01100111 0000vvvv 0000aaaa 00000000
Store %value to %address in SSD
pload_16 %dest(register), [%address(immediate)]
01110110 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from SSD and stores it to %dest
pstore_16 [%address(immediate)], %value(register)
01110111 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in SSD
mov %a(register), %b(register)
00100100 aaaabbbb 00000000 00000000
Copies from register %b to register %a
neg %a(register), %b(register)
00100101 aaaa0000 0000bbbb 00000000
Negate register %b and store the result in %a
not %a(register), %b(register)
00110110 aaaabbbb 11111111 11111111
Bitwise NOT each bit in register %b and store the result in %a
push %a(register)
00110101 11101110 00000000 00000010  01100011 0000aaaa 00001110 00000000
Pushes %a on to the stack. This instruction is a synonym for:  sub sp, sp, 2  store_16 [sp], %a
pop %a(register)
01100010 aaaa0000 00001110 00000000  00110100 11101110 00000000 00000010
Pops %a off the stack. This instruction is a synonym for:  load_16 %a, [sp]  add sp, sp, 2
call %a(label)
00001000 11110000 00000000 00000000  00110100 11111111 00000000 00010100  00110101 11101110 00000000 00000010  01100011 00001111 00001110 00000000  01011000 00001111 aaaaaaaa aaaaaaaa
Calls %a. Overwrites the flag register. This instruction is a synonym for:  counter flags  add flags, flags, 20  sub sp, sp, 2  store_16 [sp], flags  jmp %a
ret
01100010 11110000 00001110 00000000  00110100 11101110 00000000 00000010  01001000 00001111 00001111 00000000
Returns from the last function call. Overwrites the flag register. This instruction is a synonym for:  load_16 flags, [sp]  add sp, sp, 2  jmp flags
</syntaxhighlight>

Latest revision as of 11:39, 22 July 2025

wip
wip

This page descibes the early access verion 2.0.16 apha. It may not be completely correct for the the current stable version, nor the latest unstable version. Help us update it, and you get a cookie.

A number of levels in version are known to be broken, and require some workarounds to complete. Some of these issues affect multiple levels, I only give the first level you are likely to come across them.

Unofficial partial fixes[edit | edit source]

Some of the levels can be fixed by replacing the game's campaign folder with an amended version from GitHub, provided by the user ERYK500.

These are UNOFFICIAL patches - Please do not report problems to the game's developer. Instead, post on the TC Discord server in the #new-patch-talk channel.

This is a limited fix as some of the issues are engine limitations, which require a game update to resolve.

Symphony Counter[edit | edit source]

Missing bit-width tool and 16-bit

You should be able to place 16-bit components, but the bit-width tool might not be present in the level.

You can try pasting the following line into levels.txt (which is found in your save folder, check the location in Options):

symphony_register_1,true,10000,10000,0,Default

If your game is running, restart the game to ensure the changes take effect.

Some people report that the bit-width tool appears simply by going to the Sandbox then component factory. This works only if you first hoover the cursor over wire colors tool in a way that color panel stays open when the cursor is moved away and than click on Sandbox button.

If that does not work you can copy-paste 16-bit components from the sandbox.

The level log mentions "like in the register level", disregard that as that level has been removed, and this text not yet been updated to match.

Wire Spaghetti[edit | edit source]

RAM broken in Wire Spaghetti

Various issues with RAM in Wire Spaghetti and following levels.

These stem from the lack of API in test.si to identify which RAM block is the program and which is the register file.

Before attempting the following workarounds, enable the bit-width tool by following the steps in the Known issues/2.0.16#Symphony Counter section above to modify your levels.txt file, if you have not done so already. The bit-width tool will then be displayed below the wire comment tool and is required to set the bit size of the ram blocks during the following steps. You can see how wide existing RAM is by the width of the orange highlight.

WORKAROUND A:

  1. Delete the RAM for both register file and program.
  2. Set the bit width tool to 16, if you don't have it, see above or move onto B below.
  3. Place a 16-bit RAM for the register file (the size is hidden).
  4. Set the bit width tool to 32.
  5. Place a 32-bit RAM (again size is hidden) for the program.
  6. These steps should be taken in order. This might take several attempts, for reasons that are unclear to me.

WORKAROUND B:

  1. Delete the RAM for both register file and program.
  2. Copy-paste a 16-bit RAM from sandbox for the register file, then
  3. Copy-paste a 32-bit RAM from sandbox for the program.
  4. These steps should be taken in order. This might take several attempts, for reasons that are unclear to me.

WORKAROUND C:

If the above doesn't work, you can also try this, which has been reported to help.

  1. Remove the program counter (PC) from the level;
  2. Switch schematics to anything else for a moment;
  3. Return to the level;
  4. Replace the PC in its original place

Wire Spaghetti level log out of date

The level log for Wire Spaghetti states: 3. Click "Edit link components" on the program component and then "Add register file". (do not connect the zr register)

This is now wrong, zr should be linked, as part of the register file.

Bottom panel shows nop[edit | edit source]

If the bottom panel shows nop (does nothing) then first make sure the load port connected to the program counter is the lowest (nearest to the RAM). If it is see above.

RAM is byte addressed[edit | edit source]

The level log does not make clear that RAM is byte addressed (this is a change from 0.1059).

Since the register file entries are 16-bits (2 bytes) wide the register address should be adjusted to match.

r9 should have value 65535 not 0[edit | edit source]

If you see this error on tick 62, then you are writing to and reading from the zero register, this is an error in your circuit, not a bug in the game.

Integrating ALU[edit | edit source]

The ALU you previous built has a multiply instruction. The tests for Integrating ALU assume mul returns zero.

WORKAROUND: Delete or otherwise disable the multiply component inside the ALU custom component.

RAM[edit | edit source]

The level log is incomplete.[edit | edit source]

There are 4 new instructions, not the 2 listed in the level log:

  • 0: load_8
  • 1: store_8
  • 2: load_16
  • 3: store_16

The level log incorrectly states put the store port at the top, the 2 store ports should (for this level) be at the bottom, see below for my recommended ordering.

WORKAROUND: From bottom to top the ports attached to the program RAM block should be:

  1. a new 16-bit store port, then
  2. a new 8-bit store port.
  3. The existing 32 bit load port (used for instructions) should be moved above the store ports, then
  4. a new 16-bit load port, and finally,
  5. at the top, a new 8-bit load port.

The level log also incorrectly states that the 'load' and 'store' instructions should use "argument B" as address parameter. However, for this level that is not relevant. Instead you should use the immediate value as an address to store and load data in the program RAM.

As a further clarification, the 'store' instruction should fetch data from the register file at the address determined by "argument A" and store that in program RAM. The level log makes it seem as though you should store the value of "argument A" itself in program RAM, but that is not the case.

SSD[edit | edit source]

The level log is incomplete.[edit | edit source]

Similar to the RAM level, there are more instructions than shown in the level log, 4 new instructions are added, all instructions are:

  • 0: load_8
  • 1: store_8
  • 2: load_16
  • 3: store_16
  • 4: pload_8
  • 5: pstore_8
  • 6: pload_16
  • 7: pstore_16

Memory should contain value 0, at address 3, not 31.[edit | edit source]

When placing the SSD component in your symphony architecture, you might get this error. This is again a problem with the test.si file where it mistakes your program RAM with your register RAM. To fix this, try using the workarounds described in the Known issues/2.0.16#Wire Spaghetti section. Similarly, if you get the error "Set RAM size to 65536.", then that could also indicate the same problem.

Instruction aliases[edit | edit source]

Level fails to compile due to wrong meta.txt[edit | edit source]

Edit Turing Complete\campaign\symphony_9_aliases\meta.txt (found in the game's install folder, not your save files) and delete the last 4 lines of default_assembly, so that the section reads

default_assembly = `
in r1
mov r2, r1
neg r3, r2
not r4, r2
`

Level fails due to wrong test.si[edit | edit source]

Edit Turing Complete\campaign\symphony_9_aliases\test.si and replace the it all with

def get_input($scratch_space: [Int], tick: Int, $inputs: [Int]) {
    inputs[0] = 10
}

def check_output($scratch_space: [Int], tick: Int, inputs: [Int], outputs: [Int]) TestResult {
    switch tick
        0 {
            if get_register_value(1) != 10 {
                set_error(`The first instruction is supposed to move the input value (10) to r1.`)
                return fail
            }
        }
        1 {
            if get_register_value(2) != 10 {
                set_error(`The first instruction is supposed to move the input value (10) to r2.`)
                return fail
            }
        }
        2 {
            if get_register_value(3) != 65526 {
                set_error(`Negate r2 and store the result (65526) in r3.`)
                return fail
            }
        }
        3 {
            if get_register_value(4) != 65525 {
                set_error(`NOT r2 and store the result (-9) in r4.`)
                return fail
            }
            return win
        } 
}

Various levels[edit | edit source]

A number of levels' meta.txt have out of date spec.isa, these can be fixed with a simple regex

s/(^|  )([01][01])0/$10$2/g

Wrong assembly instructions[edit | edit source]

The assembly instructions for various levels is incorrect, some instructions that are bugged include, but are not limited to:

  • Store and load instructions (including pload and pstore)
  • Move, neg, and not instructions
  • Push and pop instructions
  • Call and return instructions

Several of these have the wrong Mode, wrong OPcode, or are simply outdated. Below shows the correct instructions for these functions. You can either change them in game or in the meta.txt file associated with the level.

load8 %dest(register), %address(register)
01100000 dddd0000 0000aaaa 00000000
Loads %address from RAM and stores it to %dest

store8 %address(register), %value(register)
01100001 0000vvvv 0000aaaa 00000000
Store %value to %address in RAM

load_8 %dest(register), [%address(immediate)]
01110000 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from RAM and stores it to %dest

store_8 [%address(immediate)], %value(register)
01110001 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in RAM

load16 %dest(register), %address(register)
01100010 dddd0000 0000aaaa 00000000
Loads %address from RAM and stores it to %dest

store16 %address(register), %value(register)
01100011 0000vvvv 0000aaaa 00000000
Store %value to %address in RAM

load_16 %dest(register), [%address(immediate)]
01110010 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from RAM and stores it to %dest

store_16 [%address(immediate)], %value(register)
01110011 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in RAM

pload8 %dest(register), %address(register)
01100100 dddd0000 0000aaaa 00000000
Loads %address from SSD and stores it to %dest

pstore8 %address(register), %value(register)
01100101 0000vvvv 0000aaaa 00000000
Store %value to %address in SSD

pload_8 %dest(register), [%address(immediate)]
01110100 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from SSD and stores it to %dest

pstore_8 [%address(immediate)], %value(register)
01110101 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in SSD

pload16 %dest(register), %address(register)
01100110 dddd0000 0000aaaa 00000000
Loads %address from SSD and stores it to %dest

pstore16 %address(register), %value(register)
01100111 0000vvvv 0000aaaa 00000000
Store %value to %address in SSD

pload_16 %dest(register), [%address(immediate)]
01110110 dddd0000 aaaaaaaa aaaaaaaa
Loads %address from SSD and stores it to %dest

pstore_16 [%address(immediate)], %value(register)
01110111 0000vvvv aaaaaaaa aaaaaaaa
Store %value to %address in SSD

mov %a(register), %b(register)
00100100 aaaabbbb 00000000 00000000
Copies from register %b to register %a

neg %a(register), %b(register)
00100101 aaaa0000 0000bbbb 00000000
Negate register %b and store the result in %a

not %a(register), %b(register)
00110110 aaaabbbb 11111111 11111111
Bitwise NOT each bit in register %b and store the result in %a

push %a(register)
00110101 11101110 00000000 00000010   01100011 0000aaaa 00001110 00000000
Pushes %a on to the stack. This instruction is a synonym for:   sub sp, sp, 2   store_16 [sp], %a

pop %a(register)
01100010 aaaa0000 00001110 00000000  00110100 11101110 00000000 00000010
Pops %a off the stack. This instruction is a synonym for:   load_16 %a, [sp]   add sp, sp, 2

call %a(label)
00001000 11110000 00000000 00000000   00110100 11111111 00000000 00010100   00110101 11101110 00000000 00000010   01100011 00001111 00001110 00000000   01011000 00001111 aaaaaaaa aaaaaaaa
Calls %a. Overwrites the flag register. This instruction is a synonym for:   counter flags   add flags, flags, 20   sub sp, sp, 2   store_16 [sp], flags   jmp %a

ret
01100010 11110000 00001110 00000000   00110100 11101110 00000000 00000010   01001000 00001111 00001111 00000000
Returns from the last function call. Overwrites the flag register. This instruction is a synonym for:   load_16 flags, [sp]   add sp, sp, 2   jmp flags