Ether
This code from block 900 is loaded into node 608. And from there into all the other nodes in both the target and host chips of GreenArrays' Eval board. This is the code that establishes the ether which communicates amongst nodes.
Be warned that this is the most complicated block of code that I've written. Stack comments may help:
- f for flag, distinguishing code (0) from fill
- n for count
- a for a register
- p for path
- c for count word
- j for call
The header for an ether message is 4 words:
followed by the payload.
The word e608 in the last line is special code to load this block into node 608 from async node 708.
Port calls
The first 4 words of RAM contain calls to the right, left, down and up ports. Because of the way nodes are mirrored, if you move left/right those calls must be swapped. If you move up/down those calls must be swapped. This procedure undoes the complication of mirrored nodes.
These port calls are used as the port address. That's ok because only the 9 low-order bits are the address. The call instruction in the high-order bits is ignored.
fill
This is the initial entry point. It puts a non-zero on the stack and jumps to whence. Fill will copy this block of code into every node along the path.
code
This is the nominal entry point. It puts a 0 on the stack and falls into whence.
whence
Determines from which comm port the message comes. The call following the focus call brought us here. So the focus address is on the return stack. It's put into register a where it will remain.
The next word is fetched, which is the path. Fall into turn.
turn
Examines the path:
- If the current (low-order) run is non-zero, go to wither to continue the run.
- If the next run is non-zero, shift it right and repeat turn.
- Otherwise path is finished. Copy? will copy this block of code, if desired
- Finally, forward the payload.
wither
- Decrements the current run
- Copies this code
- Forward call to next node
- Forward path
- Fetch and forward count word
- Fall into payload
payload
- Call pump to forward the payload
- Examine reply count
- If non-zero, decrement and await reply
- Otherwise finished. Return to 4-port read, whose address is now on the return stack.
copy?
- Path is on the stack. Use the 2 direction bits to fetch the correct port call
- Store into register b, the destination to forward the message
- Forward port call as the focus
- If code is to be copied
- Save and restore register a
- Call mirror to adjust the port calls
- Call copy to forward the code
- Call mirror again to restore the port calls
- Return call to fill
- Return call to code
mirror
- Register a has been saved on the stack
- The 2s bit of the path distinguishes right/left from down/up
- Saving a and fetching with increment gets 2 calls
- Restoring a and storing with increment swaps them
copy
Forwards 3 instruction words and falls into pump. The code for those words is standard transfer code in the comment line just above. The will be executed by the destination node
- Set a to 0
- Load count into R
- And read into RAM
pump
Simply moves data from the address in register a to that in b. Increment fetch is used to move data from RAM. If it is moving from a port, the increment is suppressed.