m (→Level fails due to wrong test.si: Fixed formatting) |
(→Wire Spaghetti: Added Bottom panel shows nop) |
||
(27 intermediate revisions by 10 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 | 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 == | |||
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. | |||
* [https://github.com/ERYK500/tc_campaign/ https://github.com/ERYK500/tc_campaign/] | |||
{{Note|These are '''UNOFFICIAL''' patches - Please do not report problems to the game's developer. Instead, post on the TC Discord server in the <code>#new-patch-talk</code> channel.}} | |||
This is a limited fix as some of the issues are engine limitations, which require a game update to resolve. | |||
== Symphony Counter == | == Symphony Counter == | ||
Line 10: | Line 20: | ||
You should be able to place 16-bit components, but the bit-width tool might not be present in the level. | You should be able to place 16-bit components, but the bit-width tool might not be present in the level. | ||
Some people report that the bit-width tool appears simply by going to the Sandbox then component factory. | You can try pasting the following line into <code>levels.txt</code> (which is found in your save folder, check the location in Options): | ||
<pre>symphony_register_1,true,10000,10000,0,Default | |||
</pre> | |||
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 20: | 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> | 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''': | |||
# 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 C''': | |||
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; | |||
# Switch schematics to anything else for a moment; | |||
# Return to the level; | |||
# Replace the PC in its original place | |||
[https://discord.com/channels/828292123936948244/1357729558547398837 Wire Spaghetti level log out of date] | [https://discord.com/channels/828292123936948244/1357729558547398837 Wire Spaghetti level log out of date] | ||
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 46: | Line 87: | ||
== Integrating ALU == | == Integrating ALU == | ||
The ALU you previous built has a | 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 component inside the ALU custom component. | ||
== RAM == | == RAM == | ||
Line 54: | 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> | * <code>0: load_8</code> | ||
* <code> | * <code>1: store_8</code> | ||
* <code> | * <code>2: load_16</code> | ||
* <code> | * <code>3: store_16</code> | ||
The level log incorrectly states put the store port at the top, | 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''': | ||
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 | ||
# | # a new 8-bit store port. | ||
# | # 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, | ||
# | # 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 == | ||
=== Level fails due to wrong | === Level fails to compile due to wrong meta.txt === | ||
Edit <code>Turing Complete\campaign\symphony_9_aliases\ | 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 | ||
<code><pre>def check_output($scratch_space: [Int], tick: Int, inputs: [Int], outputs: [Int]) TestResult { | <pre>default_assembly = ` | ||
in r1 | |||
mov r2, r1 | |||
neg r3, r2 | |||
not r4, r2 | |||
`</pre> | |||
=== Level fails due to wrong test.si === | |||
Edit <code>Turing Complete\campaign\symphony_9_aliases\test.si</code> and replace the it all with | |||
<pre>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 | switch tick | ||
0 { | 0 { | ||
Line 103: | Line 179: | ||
return win | return win | ||
} | } | ||
}</pre></ | }</pre> | ||
== Various levels == | |||
A number of levels' meta.txt have out of date spec.isa, these can be fixed with a simple regex | |||
<pre> | |||
s/(^| )([01][01])0/$10$2/g | |||
</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
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.
#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]
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:
- 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 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.
WORKAROUND C:
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;
- Switch schematics to anything else for a moment;
- Return to the level;
- 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:
- a new 16-bit store port, then
- a new 8-bit store port.
- The existing 32 bit load port (used for instructions) should be moved above the store ports, then
- a new 16-bit load port, and finally,
- 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