Synergy Computer v.1.0
https://powdertoy.co.uk/Browse/View.html?ID=1761441
~1761441
Specifications:
Possible future changes/additions:
Instruction Architecture:
Instructions are 29 bits in length. This is because FILT technology holds 30 wavelengths. The 30th bit (leftmost) is used to represent 0.
The first 5 bits are control bits:
[00000][...................][....................]
The next 12 bits are ARGA:
[........][000000000000][...................]
The final 12 bits are ARGB:
[........][...................][000000000000]
Assembler:
Drrs has kindly created an assembler for this computer. The assembler along with usage instructions can be found here: https://github.com/harddal/SYNASM
Using the assembler:
1. Transfer assembler contents into your Powder Toy .exe folder.
2. Create a file in this folder with the .scm extention.
3. Open file using a text editor (ie. notepad++)
4. Write assembly code. (syntax specifications found in above link)
5. Open the assembler (SYNASM.exe)
6. type the filename (*.scm)
7. If the file assembles successfully, a *.sc file of the same name will be created in the Powder Toy .exe folder. This file will contain all the assembled binary information for all of the instructions.
Example program:
DCO "@cTHIS PROGRAM WILL GENERATE THE FIBONACCInSEQUENCE...nn" ; ends at 14.
DB 0x1, 0x0 ; puts 0 in RAM1
DB 0x2, 0x1 ; puts 1 in RAM2
LD 0x1, 0x1 ; loads RAM1 to register1
LD 0x2, 0x2 ; loads RAM2 to register2
ADD 0x1, 0x2 ; adds register 1 and register 2
DIR 0x1, NUL ; displays the result from register 1
DCO "@, " ;
ADD 0x2, 0x1 ; adds register 2 and register 1
DIR 0x2, NUL ; displays the result from register 2
DCO "@, " ;
JMP 0x7, 0x13 ; jumps back to the first addition
LUA script for importing *.sc information into Synergy Computer:
Urumasi has created some LUA script that will allow you to import the *.sc file into Synergy Computer's ROM. The script sends the first instruction of the program to the address 001110000001 (c7, r1), the second instruction to 001110000010 (c7, r2) and so on. The 128th line of the program will flow over onto 001100000001 (c6, r1), and so on. This computer does not shift columns automatically, so you will be required to use JMP commands on r127 of each collumn. (ie. from c7, r127: JMP 0x6, 0x1 ;)
Using the LUA script:
1. Move .lua file to Powder Toy folder. Rename it synergy.lua. (or anything really)
2. Open Synergy Computer, and type <dofile("synergy.lua")> into the LUA console
3. Enter the name of the .sc program (without the .sc extention).
Instructions (as named by oldmud0):
00001: DB
00010: SR
00011: LD
00100: MOV
00101: ADD
00110: SUB
00111: SUBC
01000: INC
01001: DEC
01010: SHR
01011: SHL
01100: NOT
01101: NAND
01110: XOR
01111: OR
10000: AND
10001: DCO
Charset addresses:
10010: DCR
10011: DCM
10100: DCP
10101: LDP
10110: SP
10111: JNE
Unused:
[00][...][.......]
Specifies the collumn for ROM address. 1-7 This computer uses 127x7 ROM. Thus, two addresses required:
[..][000][.......]
Specifies the row for the ROM address. 1-127:
[..][...][0000000]
11000: JE
11001: JMP
11010: ICP
11011: DIR
11100: DIM
11101: DIP
11110: IIP
111111: RST
Well, I'd say those instructions are ill-named. Or rather, not named at all. ;)
Here's my proposed named opcode list:
00000: NOP
00001: DB
00010: SR
00011: LD
00100: MOV
00101: ADD
00110: SUB
00111: SUBC
01000: INC
01001: DEC
01010: RSH
01011: LSH
01100: NOT
01101: NAND
01110: XOR
01111: OR
10000: AND
10001: DCO (display character rOm)
10010: DCR (display character Register)
10011: DCM (display character raM)
10100: DCP (display character Pointer)
10101: LDP
10110: SP
10111: JNE
11000: JE
11001: JMP
11010: ICP (input character pointer)
11011: DIR
11100: DIM
11101: DIP
11110: IIP (input integer pointer)
11111: RST
...in case you are making an assembler, either in or out of TPT.
I am also wondering if you are ever going to add an INT (interrupt) opcode to alleviate the number of opcodes needed. You could also use this to communicate with peripherals like CRAY printers.
I also have a hunch: could you do addition and multiplication with FILT?
I have to say great work! I am currently getting some practice programming your computer.
EDIT:
I have made a simple adder that gets 2 numbers from the "keyboard", adds them, and displays the result. The problem is that it doesn't seem to add the numbers correctly. No matter what I input I always get 32 as the output. I used Oldmud0's naming convention for the pseudo-ASM code that I retyped in binary and converted to decimal to set the filt's ctype with the prop tool. Any help would be appreciated, note that I am a noob when it comes to this type of low level programming.
DB 0x0, 0x0 ; Store value 0x0 to adress 0x0
LD 0x0, EAX ; Move value 0x0 to register 0
IIP EAX, NUL ; Get input and write to ram at 0x0
DB 0x0, 0x1 ; Store value 0x1 to adress 0x0
LD 0x0, EAX ; Move value 0x1 to register 1
IIP EAX, NUL ; Get input and write to ram at 0x1
LD 0x0, EAX ; Move contents of adress 0x0 to register 0
LD 0x1, EBX ; Move contents of adress 0x1 to register 1
ADD EAX, EBX ; Add the contents of registers 0 and 1 together
DIR EAX, NUL ; Display contents of register 0
Instructions converted to binary and decimal to set filt ctype:
1000000000000000000000000 ; 16777216
11000000000000000000000000 ; 50331648
11110000000000000000000000000 ; 503316480
1000000000000000000000001 ; 16777217
11000000000000000000000000 ; 50331648
11110000000000000000000000000 ; 503316480
11000000000000000000000000 ; 50331648
11000000000001000000000001 ; 50335745
101000000000000000000000001 ; 83886081
11011000000000000000000000000 ; 452984832
EDIT:
I have also gotten a compiler for the assembly code thrown together in c++. It takes in the assembly and spits out the binary instructions that can be loaded with the lua script that is posted in the comments on the save.
Wow I would be interested to see that :)
As for addition. Hmm, If it's outputting 32 all the time, it could be that it's adding 31 and 1. 31 is the default FILT value if I remember correctly.
I would do something like (excuse me for not using the syntax yet).
write 10 to RAM1.
load RAM1 -> REG1
input int to RAM(REG1) (so it sends the value to RAM10)
write 11 to RAM1
load RAM1 -> REG1
input int to RAM(REG1) (so it sends the second value to RAM11)
RAM10 -> REG1
RAM11 -> REG2
ADD REG1, REG2
OUTPUT REG1.
Try this and let me know if you're still getting 32. I think the problem is that RAM addresses begin at 1 (stupid I know), and you thought they began at 0. Is that what was stopping it from working?
Thanks for that! I've never created such a thing before, so I would have to learn how first. It looks like there's more capable people than myself like drrs looking into it. As for interupt, that would be interesting. I don't think there are any computers in PT that have an interupt yet. It's difficult to implement I think.
I think I implemented what you said correctly but the addition is still off. It works but 2+3 comes out to 4 and 5 + 4 comes out to 7. It is adding the numbers but something is making the result come out smaller than it should be. Here is the code, I seperated the 29 bit groups for easy reading:
00001 000000000001 000000001010
00011 000000000001 000000000001
11110 000000000001 000000000000
00001 000000000001 000000001011
00011 000000000001 000000000001
11110 000000000001 000000000000
00010 000000001010 000000000001
00010 000000001011 000000000010
00101 000000000001 000000000010
11011 000000000001 000000000000
Here is the source to my compiler and the download link. It uses the keywords Oldmud posted and recognizes EAX and EBX as the first two of the 10 registers. To use just give it the name of a file with the SYNASM code (thats what I am calling it) and it will generate a *.sc file with the binary instructions. Note that it isn't totally bug free but seems to work pretty well if the code is formatted correctly. It will probaly require the Visual Studio 2013 redistributable to run.
Source: http://pastebin.com/nrH6RDX0
EXE: https://drive.google.com/file/d/0B9aPKDgFnabZVTlXVkh6bHUwTXM/view?usp=sharing
I can make a small guide of how to write the assembly code if you want.
00010 000000001010 000000000001
00010 000000001011 000000000010
these two instructions should be 00011. If you're loading to registers from RAM. I think that's what is wrong.
Yes it would be very helpful if you showed me how it's formatted :p Particularly the DCO instruction.
Hmm something is strange. I could be wrong, but I think that lua script is deleting or modifying something. For whatever reason, it sends the address to the registers without the 0 bit activated. Which is strange, since the code in my computer does this operation hundreds of times, and the 0 bit is always activated.
I think I found it. The real problem is that the lua script doesn't add the 0 value to the instructions. So we need to modify the lua script to always add the 30th bit. Once this is done, everything should work fine. The problem was, that without the 30th bit set to 1, the register address XOR demultiplexor was trying to XOR 1000000000000000000000000000001, when it was recieving 000000000000000000000000000001.
In the meantime, I will just add a piece of FILT somewhere to manually add the bit back in.
Once I fixed those two commands it worked, thanks! As for the issue with the lua script, I never would have caught that.
The compiler I wrote doesn't support the DCO command yet, I am working on being able to write the 4 letters you want to use in a string literal in the assembly. But all other commands should be functional. As for using them it is formatted like:
[CMD] [ARGA], [ARGB]
So writing 10 to RAM1 would be:
DB 0x1, 0xA
Numbers in the assembly are in hex to shorten it up. For commands without an ARGB you type NUL:
DIR 0x1, NUL
You can also use EAX and EBX to specify registers 1 and 2:
ADD EAX, EBX
It also supports code commenting with the semicolon:
IIP EAX, NUL ;Get number from user input to register 1
Thats pretty much it. As I said I am working on using string literals for the DCO command, when I get that done it would be used like this:
DCO "DR", "RS" ;Write my forum name to the screen
Here is the working code for the adder you have been helping me write in assembly:
DB 0x1, 0xA
LD 0x1, EAX
IIP EAX, NUL
DB 0x1, 0xB
LD 0x1, EAX
IIP EAX, NUL
LD 0xA, EAX
LD 0xB, EBX
ADD EAX, EBX
DIR EAX, NUL
I also made a plugin for Notepad++ that will add syntax highlighting to the assembly code, here is the download if you want it: https://drive.google.com/file/d/0B9aPKDgFnabZSW1FT0I0eTlHQVU/view?usp=sharing
It detects the *.smc file extension and my compiler will take that in and spit out a *.sc