The machine consists of data memory, program memory, a program pointer, data pointer, and the adjustment register. The word size n is unspecified but is at least 14 bits. (It is 14 bits in the reference implementation.) There are 2^n cells each in program memory and data memory. Cells in data memory are one word; cells in program memory hold one instruction. The three registers are each one word.
The program pointer and data pointer are initially 0. The adjustment register is initially 1.
A machine cycle consists of fetching the instruction pointed to by the program pointer, executing the instruction, and except for a true conditional jump, adjusting the program pointer by exclusive-ORing it with the adjustment register. For a true conditional jump, the program pointer is exclusive-ORed with all 1s (that is, complemented).
- ^ rotate the adjustment register left
- v rotate the adjustment register right
- > adjust the data pointer
- + adjust the cell pointed to by the data pointer
- . output the cell pointed to by the data pointer
- , input to the cell pointed to by the data pointer. If end-of-file, the high bit is set.
- $ if the cell pointed to by the data pointer ANDed with the adjustment register is not 0, complement the program counter instead of adjusting it
- ! halt
"Adjust" means to exclusive-OR with the adjustment register.
You could specify a program by listing the whole program memory, but that would need to include a lot of unused instructions. So you can specify the address in hexadecimal followed by a colon, before a series of instructions. The series of instructions are specified in ascending order of addresses taken as binary numbers, starting with the specified address (even though the machine has no concept of incrementing binary numbers, so the instructions won't be executed in that order).
Program Cat 0: ,v^^ 2001: v 1001: $v 2FFE: ! 3000: .^vv 2002: +
The instruction at address 0 is ',', so the first thing it will do is ask for input. The 'v','^','^' are at addresses 1, 2, and 3 respectively. Then, there is a 'v' at address 2001; then '$' at 1001 and 'v' at 1002. And so on.
Non-instruction characters are ignored so the "Program Cat" heading is just a comment with no effect.
In order to make programs portable to bigger word sizes, the addresses can be specified in a more versatile way with two operators. The `_` operator reverses and left-aligns its left operand, and ORs it with the right operand. A '~' precedes the whole address, and complements it; this is useful for the target of a jump instruction. `_` has higher precedence than `~`; that is, a `~` complements the whole thing.
Here is the Cat program written for portability:
Program Cat 0: ,v^^ 1_1: v 2_1: $v ~2_1: ! 3_0: .^vv 1_2: +
You can also use 'O' and 'l' to specify addresses in binary instead of hexadecimal (those are letters, to distinguish them from hex digits; they are case-insensitive).
Propagating carries is "expensive" in terms of electronic circuitry, because each bit's result is a function of all the less-significant bits; with bitwise exclusive-ORs each bit is a function of the two operand bits only. So there might be an electronic justification for this design, to make a CPU with very few logic gates.
Yboy is certainly not Turing-complete, as the memory is finite; beyond that, its power is still unexplored.