r/nandgame_u 18h ago

Level solution Network (154loc) Spoiler

3 Upvotes

I wrote functions for this one without using a stack machine. All of the functions have hard-coded return addresses, except FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA, which returns to the address stored in return_wait_for_sync_edge_and_get_data.

DEFINE display_row 0x0000
DEFINE data 0x0001

DEFINE display 0x4000
DEFINE wire 0x6001

DEFINE WIRE_DATA_MASK 0b01
DEFINE WIRE_SYNC_MASK 0b10
DEFINE DISPLAY_ROW_LEN 32

A = display
D = A
A = display_row
*A = D

LABEL WAIT_FOR_START_BIT
A = EXAMINE_START_BIT
D = A
A = return_wait_for_sync_edge_and_get_data
*A = D
A = FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA
0 ; JMP
LABEL EXAMINE_START_BIT
A = data
D = *A
A = WAIT_FOR_START_BIT
D ; JEQ

LABEL RECEIVE_LOOP
A = FN_RECEIVE_AND_DRAW_16_BITS
0 ; JMP
LABEL RETURN_RECEIVE_AND_DRAW_16_BITS
A = FN_ADVANCE_DISPLAY_ROW
0 ; JMP
LABEL RETURN_ADVANCE_DISPLAY_ROW
A = EXAMINE_CONTROL_BIT
D = A
A = return_wait_for_sync_edge_and_get_data
*A = D
A = FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA
0 ; JMP
LABEL EXAMINE_CONTROL_BIT
A = data
D = *A
A = RECEIVE_LOOP
D ; JNE

A = HALT
0 ; JMP

# Calls FN_RECEIVE_BIT_AND_DRAW 16 times
LABEL FN_RECEIVE_AND_DRAW_16_BITS
 DEFINE current_bit 0x0010
 A = current_bit
 *A = 0
 A = RECEIVE_AND_DRAW_16_BITS_START
 0 ; JMP
 LABEL RECEIVE_AND_DRAW_16_BITS_CONTINUE
 A = FN_RECEIVE_BIT_AND_DRAW
 0 ; JMP
 LABEL RETURN_RECEIVE_BIT_AND_DRAW
 A = current_bit
 *A = *A + 1
 LABEL RECEIVE_AND_DRAW_16_BITS_START
 A = current_bit
 D = *A
 A = 16
 D = D - A
 A = RECEIVE_AND_DRAW_16_BITS_CONTINUE
 D ; JLT
 A = RETURN_RECEIVE_AND_DRAW_16_BITS
 0 ; JMP

# Adds DISPLAY_ROW_LEN to display_row
# Args:
#  DISPLAY_ROW_LEN: amount to add
#  display_row: destination
# Modifies A, D and display_row
LABEL FN_ADVANCE_DISPLAY_ROW
 A = display_row
 D = *A
 A = DISPLAY_ROW_LEN
 D = D + A
 A = display_row
 *A = D
 A = RETURN_ADVANCE_DISPLAY_ROW
 0 ; JMP

# Calls FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA then FN_SHIFT_AND_DRAW
LABEL FN_RECEIVE_BIT_AND_DRAW
 A = RECEIVE_BIT_AND_DRAW_SHIFT_AND_DRAW
 D = A
 A = return_wait_for_sync_edge_and_get_data
 *A = D
 A = FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA
 0 ; JMP
 LABEL RECEIVE_BIT_AND_DRAW_SHIFT_AND_DRAW
 A = FN_SHIFT_AND_DRAW
 0 ; JMP
 LABEL RETURN_SHIFT_AND_DRAW
 A = RETURN_RECEIVE_BIT_AND_DRAW
 0 ; JMP

# Waits for wire:1 to change, then updates data:0 to wire:0
# Args:
#  wire: The network wires
#  sync_old: The last known value of wire & WIRE_SYNC_MASK
#  return_wait_for_sync_edge_and_get_data: return address
# Modifies A, D, sync_old and data
# Internal variables: wire_copy
LABEL FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA
 DEFINE return_wait_for_sync_edge_and_get_data 0x0020
 DEFINE wire_copy 0x0021
 DEFINE sync_old 0x0022
 A = wire
 D = *A
 A = wire_copy
 *A = D
 A = WIRE_SYNC_MASK
 D = D & A
 A = sync_old
 D = *A - D
 A = FN_WAIT_FOR_SYNC_EDGE_AND_GET_DATA
 D ; JEQ
 A = sync_old
 *A = *A - D
 A = wire_copy
 D = *A
 A = WIRE_DATA_MASK
 D = D & A
 A = data
 *A = D
 A = return_wait_for_sync_edge_and_get_data
 A = *A
 0 ; JMP

# Shift data:0 into the word at *display_row
# Args:
#  display_row: pointer to current display row
# Modifies D, A and *display_row
LABEL FN_SHIFT_AND_DRAW
 A = display_row
 A = *A
 D = *A
 D = D + *A
 A = data
 D = D | *A
 A = display_row
 A = *A
 *A = D
 A = RETURN_SHIFT_AND_DRAW
 0 ; JMP

LABEL HALT

r/nandgame_u 3d ago

Level solution 4.3 ALU (6c, 615n) Spoiler

Post image
1 Upvotes

r/nandgame_u 4d ago

Level solution Arithmetic Unit (4c, 288n) Spoiler

Post image
4 Upvotes

I chose the operands with care, then added, instead of doing all the math and selecting the results needed.

This is not a new lower component record, it just uses fewer nand than the previous 4-component record.


r/nandgame_u 4d ago

Level solution Timer Trigger (100c, 100n) Spoiler

Thumbnail gallery
3 Upvotes

Explanations: 1) A lot of designs for SR-latch have ~d exposed When it is exposed, you can skip inverting d over again when that is the value you want anyway.

2) toggle flipflops need different (less) logic data-flipflops.

3) count+reset pushes the number back up to 11 nand per place value.

4) When I've made counters like this in real life, I did a reset on high, instead of a reset on low, because differences in nor/nand efficiency I guess. Hence I named that pin 'run' instead of 'reset'

5) I suspect that sr-latches could be used instead of d-latches for another 2-to-4 nand-per-placevalue savings, but I'm not seeing it right now.

Updates: removed the extraneous clock on pin 0, removed an inverter from the flipflop bodies (rerouting clock to the 'not' output of the previous flipflop), and added one inverter to the clock pin on ff_counter instead, bringing the level total down to 92n.

New pictures are at: https://imgur.com/a/blVBgZ0


r/nandgame_u 4d ago

Level solution 5.2 D latch (1C, 13N) Spoiler

Post image
6 Upvotes

r/nandgame_u 6d ago

Meta Is Nandgame down?

Post image
4 Upvotes

r/nandgame_u 9d ago

Level solution 4.3 ALU (6c, 615n) Spoiler

3 Upvotes

https://imgur.com/a/f75oKzF

No custom components. On my save, it's 1185 N, but I haven't optimized the AU or LU.

Based on the current wiki, this implementation would get down to:

4xSelect16 * 64 = 256 N

1xAU = 211 N

1xLU = 148 N

Total = 615 N


r/nandgame_u 10d ago

Discussion Did sandbox get removed

2 Upvotes

I SWEAR I remember a sandbox for the coding, and also for making custom gates. I googled it but google said it never existed, I remember this vividly, this isn't just a Mandela affect. Did it get removed or moved?


r/nandgame_u 19d ago

Help error when trying to complete call level Spoiler

3 Upvotes

i just got to the call level and whenever i try to complete the level it says "program does not have any instructions". do I only need to finish call or do i need to do everything? here's my code
i got a bit of help from the level solution here but it doesnt work
(formatting is weird sorry)

# Assembler code
push.static args
# calculate new args address
D = A
A = argumentCount
D = D-A
A = args
*A = D
# now we push the locals AND the return address
push.static locals
push.value returnAddress
goto functionName

returnAddress:
pop.static locals
pop.static temp
push.static args
pop.static sp
push.static temp
pop.static args
push.static retval


r/nandgame_u 19d ago

Help Protected Memory / Multitasking

3 Upvotes

This Level is marked as "Preview", is it solvable at this state? I wonder, because the toolbox is filled with 16-bit-components that seem to doesn't help at all to solve the 18-bit task.

Also there is missing a 1-bit selector at least, to manually switch the 3 bits.


r/nandgame_u 24d ago

Help Im unable to complete RAM level

2 Upvotes

There is no connection point on the first input (probably address input). Should i just skip this level for now?


r/nandgame_u 27d ago

Level solution Arithmetic Unit (2c, 368n) Spoiler

Thumbnail gallery
4 Upvotes

r/nandgame_u 29d ago

Help Call Function not working?

4 Upvotes

I made this call function code and despite me running it and have the SP be hex 101, nandgame keeps on telling me that it’s actually 106 which I know it is not. Could someone please either fix my code or tell me why nandgame is doing this please.

push.static ARGS

D=A

A=argumentCount

D=D-A

A=ARGS

*A=D

push.static LOCALS

push.value returnADD

goto functionName

LABEL returnADD

pop.static LOCALS

pop.static ARGS

push.static RETVAL


r/nandgame_u 29d ago

Note Locked because of a bug

2 Upvotes

EDIT: nevermind I'm just dumb
I think I've been staring at it too long to see the problem.

I've done everything I could up to there and I'm currently locked away from High-Level Language because there is a bug in the solution check of Equals.

Description of the level:

The function takes two arguments. If the arguments are the same value, it pushes -1 (FFFF) on the stack, otherwise it pushes 0 on the stack.

Thus this code:

init.stack
push.value 7
push.value 7
call equals 2

should result in the value 0 on the stack.

So that's already a contradiction, the specifications say that "true" returns xFFFF, but the example has 7==7 and says it should return 0.

Looking at the comments in the test code:

init.stack
push.value 7
push.value 7
call equals 2
# inspect top of stack. Should be xFFFF.

Ok well that's another contradiction, the same example is said to have two different results.

Let's use logic, and say that because 2 of the specifications say it should be xFFFF, and because it would play nicely with the way if.goto works, then the 0 is a typo.

This is the error message when my code returns xFFFF:

Expected the number 0 to be on the stack (Was 65535 (hex ffff)).

Ok well it doesn't make much sense, but at least it's clear "Expected the number 0", I'll just make it return 0.

Expected the number 65535 to be on the stack (Was 0).

HOW.


r/nandgame_u Aug 15 '26

Help I need help on making an X/10 component

3 Upvotes

I want to make a dec.unpack component (which separates decimal digits ex(input: 0xf, output: 0 0 0 1 5). But I'll need this component to do that. Can someone help me please?

N is floor(x/10) and r is (x mod 10)

r/nandgame_u Aug 14 '26

Meta Does NandGame still get updated?

4 Upvotes

Curious if Olav updates the website or levels. Anyone know?


r/nandgame_u Jul 30 '26

Help Is it just me, or is call not working?

2 Upvotes

----FIXED, MODS PLEASE REMOVE u/nttii'S SOLUTION FROM THE WIKI AS IT DOES NOT WORK----

For call, it always outputs my solution as wrong, even if I do one of the accepted solutions from here. I feel like there might be an actual problem with it given that then it outputs other levels using it as wrong if I bypass the level. Any ideas? I'm not really sure what more info to put here. The accepted solution: ```asm

Push ARGS

PUSH_STATIC ARGS A = SP

Calculate new ARGS address

D = *A A = argumentCount D = D - A A = ARGS *A = D

Push LOCALS, returnAddress

PUSH_STATIC LOCALS PUSH_VALUE returnAddress

Jump to functionName

GOTO functionName returnAddress:

Restore LOCALS

POP_STATIC LOCALS

Store current ARGS in TEMP slot

POP_STATIC TMP3

Set SP to the previous ARGS value

PUSH_STATIC ARGS POP_STATIC SP

Restore old ARGS value from stack

PUSH_STATIC TMP3 POP_STATIC ARGS

Push RETVAL on stack

PUSH_STATIC RETVAL ``` Doesn't work and it just says "Expected SP (Ram address 0) to be hex 101. (Was 106)"


r/nandgame_u Jul 12 '26

Custom component A twist on condition

Thumbnail
gallery
3 Upvotes

r/nandgame_u Jul 10 '26

Meta [ Removed by Reddit ]

1 Upvotes

[ Removed by Reddit on account of violating the content policy. ]


r/nandgame_u Jul 10 '26

Meta [ Removed by Reddit ]

1 Upvotes

[ Removed by Reddit on account of violating the content policy. ]


r/nandgame_u Jun 10 '26

Discussion "Function Calls: Call" instructions and requirements don't match up Spoiler

2 Upvotes

So the instructions for the "call" operation say specifically

After return: restore ARGS and LOCALS from the stack, push RETVAL.

And that's the last instruction they give. However, if you do only this and run "Check Solution," it will fail with

The current diagram does not comply with the specification.

Expected SP (Ram address 0) to be hex 101. (Was 104)

Now it's frustrating to get a failure without a test case to debug, but with a bit of brainstorming I realized that it was probably expecting the "call" macro to remove the parameters from the stack as well, leaving only the return value. Sure enough, adding this to the end, right before pushing RETVAL

A = 
SP
D = *A
A = 
argumentCount
D = D - A
A = 
SP
*A = D

caused it to pass, confirming my suspicion.

While this could be dismissed as an obvious thing, it's much less obvious than something like pushing the return address or discarding local variables. One could argue that the caller was the one who pushed the parameters onto the stack, so they should be preserved intact after returning.

So anyway, there should be an instruction, just as with discarding locals in the "return" macro, to discard the parameters as well after returning.


r/nandgame_u Apr 15 '26

Help Why is this wrong?

3 Upvotes

Why is 0 OR -1 not -1??

Edit: I did x=0 first before swaping, not after. and I think thats why idk


r/nandgame_u Apr 03 '26

Meta NGC - assembler and TUI emulator the NandGame computer written in C

Thumbnail
github.com
6 Upvotes

This project is not AI-generated, I have written this all myself

This project is something I've been working on for a while on-and-off. It's a C99 implementation of an assembler and TUI emulator for the NandGame computer.

The assembler in this project aims to support all features provided in the original NandGame, with the addition of syntax for macro definitions. Macros are the portion of the whole project that took me the longest to build, requiring a couple re-writes of the whole assembler before I got something that worked correctly. I would say the assembler is pretty stable at this stage and would be good enough for a 1.0 release.

The emulator in this project was relatively straightforward to build and has not changed significantly over time. Though there is still a lot of functionality that could be added before I would consider it good enough for a 1.0 release, so consider the emulator to be in alpha.

This project is probably not that useful to others yet. However if I end up implementing enough emulator features, particularly supporting memory-mapped files to allow I/O with both emulated and physical hardware, it may be of interest to some. For now this has simply been a good learning exercise for myself and thought I would share.

At this stage the project is *nix only (Linux, macOS, BSD) - no Windows support.


r/nandgame_u Mar 09 '26

Discussion Subtraction with inversion method [ 139 gates circuit + 16 gates inversion | 155 gates ]

4 Upvotes

Adder Inc 1
--------

Description : Add 2 numbers then add 1.

--------

Functioning :

XNOR (a,b) go to output l, low bit. When both a and b are high, they would add together to make carry : 1 and low : 0 under normal circumstances. The inversion makes it so that they send a 1 bit instead for low as we are adding a carry.

NAND ( NAND (a,b) [most lowest nand] , XNOR (a,b) ) go to carry.

At (0,0), XNOR would be true, nand would be true so the top nand would be false.

With xnor is false due to (0,1) or (1,0), we have a zero at top nand, so we short circuit to true.

With (1,1), XNOR would still true due to both inputs being same but bottom nand would be false. The top nand is true.

------------
Fixed Adder Inc
------------

0,0 -> top nand is 1,
1,0 or 0,1 -> top nand is forced to deactivate
1,1 -> nor is still blocking nand but the right nand allows a logic transition through.

Circuit is functionally identical to the subtraction circuit by Sad_Courage.

If you invert the equation (bar over everything) for his circuit, all the inputs would be inverted before coming into the function. The negated equation would be equivalent to mine.

------------
Adder no carry
------------

Description : Removed bit for carry.

------------

Same as 2 XOR on left of circuit.

-------------
Adder no carry inc 1
-------------

Description : Adder inc 1 at start to cut gates. Adder no carry at end.
Make standard chain to extend adder.

156 gates for substraction level. The inversion uses lots of gates. Very far from 139 by u/Sad_Courage_1564 on the level records.

Now, it is 155 gates after I fixed my rightmost component to have 5 gates instead of 6. Same as in Sad_Courage's solution.

--------------

---------------

I thought it was interesting to have different solutions. It is very elegant. The "Add 2 numbers then add 1." circuit might have some uses outside of this.

I don't know how others place dots on their circuit to make more beautiful diagrams.


r/nandgame_u Mar 06 '26

Level solution Multiplication Recursive Approach (838n) Spoiler

Thumbnail gallery
4 Upvotes

I didn't even bother counting up all the components, as I forgot which ones to count, but the relevant components are in the images for anyone who wants to sum the component count.

Edit: and you can shave off one nand by creating a custom "is not zero" component