Hey, LBPHacker here!
Ladies and gentlemen, I present you Ray16, a 16-bit computer with 2 kibibytes of memory, 8 IO ports and 10 instructions.
Its ID is 1748157. It currently contains the computer itself, 16-bit input panels connected to ports 0 and 1, and 16-bit output panels connected to ports 2 and 3. Copies of these panels can be found in the top right corner.
The memory is the rectangle of FILT. The coordinates of the top-left corner of the memory are (224; 235). Don't confuse that rectangle of FILT with the other three similar blocks; they look similar but have different purposes.
Both code and data reside in the memory (which is kind of a hard drive too as its content does not change until it's changed explicitly by the computer), this allows for easier programming as the programmer does not have to maintain two separate blocks of memory. It has some caveats, that's for sure, but let's face it, that's how I built it. Fear not though for this save is just a proof-of-concept, so this might change in the future.
Execution of the program is started by SPRKing the button located at (166; 256), the one that looks like a play button; this is the Start button (duh). SPRKing this button will reset the computer so that the Instruction Pointer will point to 0x0000 (this reset does not affect the registers, the flags or the memory).
Execution may be paused by SPRKing the button above the Start button, this is called the Stop button. This disables the clock source of the computer, but does not affect it in any other way.
Execution may be resumed by SPRKing the button below the Start button, this is the Resume button. This re-enables the clock source.
The input panels may be a bit tricky to use. Usage of these requires basic knowledge of binary numbers. Sixteen squares are seen, these are used to indicate the value stored in the panel. A hollow square represents a 0, a filled one represents a 1, the least significant bit being shown in the rightmost square. SPRKing a green switch activates the corresponding bit (the square below the switch), the red switches do the exact opposite.
The output panels look similar and work almost like the input panels, except that they don't accept user input. They indicate the value of the port they are connected to the same way input panels do.
Let's see if the tilde works here
One of the most complicated parts of the computer. Heavy use of DRAY and various other RAYs allows the memory to be quite fast and be done with a read or a write operation in 8 frames. Thats's a good thing, as memory operation instructions have to be read from the memory and processed (that's two memory operations) in a 16 frame window, which is not that much.
It consists of 1024 (64x16) cells, each storing 16 bits (actually 30, but the two most significant bits are not used and bits 16-27 are reserved for the 28-bit wide instruction set), yielding 2 kibibytes of memory.
Writing to location 0x0000 and 0x0001 will not alter the same cell of the memory, as the locations are represented in cells, not in bytes. Yes, that means it's not possible to actually address 0x0001. Addressing 0x0001 is the same as addressing 0x0002 on a computer in real life. The highest possible address is 0x03FF, the bits above bit 9 are not considered.
The pixel of FILT representing address 0x0000 is in the top-left corner of the block. The one representing address 0x0001 is on its right and the one representing address 0x0040 is right below it, and so on.
Read this very carefully, then re-read it as many times as needed. It might not be as obvious as I think it is, so just ask me if something is not clear.
The instruction set is 28 bits wide, which means every instruction is a 28-bit value, not a 16-bit one. Storing instructions in one pixel of FILT is possible due to FILT being able to store 30 bits in its CTYPE field, not just 16. Some may consider this cheating, I consider it hackish use of resources.
The sixteen least significant bits of the instructions usually represent immediate values. The structure of an opcode of an instruction is shown below (bit-by-bit):
The following instructions are supported (the four digits being bits 24-27 of the opcode):
*: Flags are not updated if bit 24 of the opcode ("f") is set.
**: The bits above bit 4 of the secondary operand are not considered. The shifts become rotates if bit 24 of the opcode ("f") is set.
Sample opcodes:
This is actually the disassembly of the program currently residing in the memory provided with the save. Can you tell what it does? It adds up the values of the two input panels, prints the result on the bottommost output panel and the carry on the one above it.
I've been builing this computer for two weeks now, and every time I add something to it I check if adding that something broke some other thing or not, so there shouldn't be any bugs in there, but you can never be sure. I'd appreciate if you told me if you found a bug.
Should any questions arise, feel free to ask anything below.
This is the first time I'm posting something here, so please let me know if you think I could somehow improve the wording, layout or whatever of this post. I'll be updating this post quite frequently, as I'm bound to make typos here and there. You know how it is with posting. Thanks for reading!
Thanks, it means a lot!
Here's an extension to the OP.
The status of the computer is stored in five flags:
While flags may be altered indirectly using flag-altering* instructions, directly altering flags is not possible.
*There are ALU instructions which don't alter the flags at all. See the Programming section below.
You can either choose to program Ray using the PROP tool and the Instruction Reference above, or you can fetch the Ray Assembler (http://lbphacker.hu/powdertoy/rasm.lua) and run it from the TPT console after opening the save. Lua gurus have an advantage here.
loadfile("rasm.lua")("some_program.asm")
Of course this assumes that rasm.lua and some_program.asm reside in the directory where TPT is installed.
The syntax itself is pretty simple; here's the default program from above in Ray Assembly:
in ax, 0 ; comments are at the end of the line preceded by a semicolon
in bx, 1 ; the commas are not important, I could write "in bx 1" if I wanted to
add ax, bx
out ax, 3
mov ax, 0
jnc nocarry ; the script is smart enough to find labels defined later in the code
mov ax, 1
nocarry: ; the name of the label is followed by a colon
out ax, 2 ; a dumb way to display the carry of the addition
hlt
I'm sorry, the editor ate the tabbing here. I swear the comments were organized into a nice column when I pasted the code.
The instructions have the exact same names as the ones in the Instruction Reference section. There are new instructions as well:
CMP: compare the two operands; works like SUB but doesn't store the result
TEST: mask the two operands; works like AND but doesn't store the result
ADDS, ADCS, SUBS, SBBS: like their S-less counterparts, but these don't alter the flags
There's a prefix called nores; it tells ALU instructions not to store the result. Yup, that means cmp actually translates to nores sub.
you lost me at 16 bit computer, but I read it regardless and what I learned is that it can perform simple addition and subtraction as well as some advanced functions that I will probably never learn. your instructions (as you said) will probably only be understood by those with the knowledge of binary computing, But regardless sweet save!
EDIT: For those of us too nooby to understand anything, can you label the specific pieces such as the ALU and the different memory sections in the save, there appears to be enough room in some spots for it.
Very nice. It's good to see that you made use of that constant time adder. Was sad to see that it got absolutely no attention when you published that.
I would suggest creating a more interactive default program. People are far more likely to upvote if they see the computer do something tangeable and easy to understand.
I've also been in the process of creating parts for my computer over the last couple of weeks.
Here you go. I've also linked this in the original save.
@Synergy (View Post) (point-by-point)
Thanks! I knew somebody would point that out. Yeah, the adder didn't get too much attention, but as a matter of fact, it got way more than I expected. It was just an adder not connected to anything interesting, after all.
I'd happily do that if I had any idea what kind of program it should be. The most user-friendly parts of the save are the IO panels, and even those are not *that* user-friendly. Maybe I should wire a firework launcher up to port 4 and do some tricks with that ...
I'd very much like to see how that turns out. I know I'll see it when it's done as computers are not published every other day, but in case you feel like showing off, I'm all ears.
Hear that? That goes for every one of you, computer developers of TPT.
...It's beautiful. *sheds a small tear*
I have absolutely no clue how to use it, but I know, deep down inside... That it's a thing of beauty.