AttoASM

AttoASM is a language designed for the AttoWPU experimental processing unit, as part of the WPU (Weird Processing Unit) concept. AttoASM is the assembly language of the AttoWPU unit and thus corresponds to the basic operation of this architecture. Both AttoWPU and AttoASM use very minimalistic design and support only three elementary instructions that change individual bits on a bus. By a series of these elementary operations, various internal units can be controlled to perform various tasks.
== WPU ==
AttoASM and AttoWPU are part of the WPU concept. WPU stands for Weird Processing Unit, which is basically series of various experimental processors (architectures) that try to be interesting, new, original, extraordinary, different or just plain weird. WPUs try to be original and playful and they usually go beyond the boundaries of convention - things we consider normal.
WPU can be any processor, that has at least part of it designed in a weird, unusual way, that makes programming for it and the way the machine code is executed challenging and/or interesting. It doesn't have to be practical in any way, as some of the architectures are more of a "hey, let's try this and see what happens" philosophy - purely experimental, whacky and weird for the sake of fun and curiosity, however sometimes there springs something really useful from all this that can be actually used for some improvement.
== AttoWPU ==
While WPU is common name for any processing unit, attoWPU is a specific WPU and not just that: it's the first WPU created as the start of the series of WPUs, so it's sort of the gateway into the world of the weird processing units. It's certainly not the best of them, or most original of WPUs, but it's a start.
AttoWPU is inspired by the microcode of normal processors and basically builds on the idea, that we can divide processors into two logical parts: execution unit (everything that does various calculations and operations) and control unit (part, that decodes instruction opcodes and tells execution unit what to do). AttoWPU has the control unit reduced to absurd minimum, requiring programmer to basically create a code, that will control the processor's function using three elementary instructions (attoinstructions), each one changing always only one bit. Regarding the execution units, AttoWPU has many of them and they do a lot of job by themselves, to make the programming simpler.
This basically allows you to either create conventional (or not) software using the attoasembly language used to control the parts of the processor, making it a form of hardcore programming, or to use the attoassembly to define a processor's function and let it process higher level instructions of your design. There's also another peculiar perk: because the attocode memory is read/write, it's theoretically possible to create self modifying processor.
There's also another task, related to AttoWPU programming: code optimization and compression. AttoWPU machine code provides a lot of space for program optimization (both making it smaller and run faster, these two are actually equal to some point) and compression (a lot of redudancy), so it's possible to test programming skills in various challenges and competitions.
In short, AttoWPU has the AttoCore, which is capable of processing only elementary instructions, called attoinstructions. AttoWPU has one 64 bit bus, which is divided into four logical buses: address, control, data and Quick aJump bus, each attoinstruction changes always one bit of this bus. There are various units (execution units) connected in parallel to these buses, so programmer must use the buses to instruct them what to do and allow them to exchange data using the data bus. The attoCore is only capable of changing one bit on one of the logical buses at each cycle, everything else must be handled by controlling the units. For better understanding the AttoWPU schematic is recommended.
Thanks the the bus design, the architecture is modular and can be easily modified - new units can be added and removed, while the AttoCore and base operation remains the same. The standard specification provides several units for integer and floating point arithmetic and input and output with easy interface, allowing to quickly get visual feedback in the simulator.
== AttoASM ==
AttoASM is a programming language used to create an attocode - machine code that's processed by the attocore of the AttoWPU. It allows programmer create the attocode by writing individual attoinstructions, but it also provides ways of simplifying the programming and reducing repeating source code. The same thing can't be however said about produced machine code, so if you want to optimize the resulting code, source code will probably be more complex and harder to manage or even create, which can present a certain challenge to programmers.
=== Simplest Example ===
 2 1 // sets third bit (address 2) 
=== Hello World Example ===
Following code presents a Hello World application in AttoASM, that writes the "Hello World!" message on the 40x4 ASCII text display, that's part of the specification.
 /* Hello World in AttoASM by Frooxius, slightly optimized, 5/20/2011, www.attowpu.solirax.org */
 
 EXE { CTRL+7(2) ! }		// execute command
 
 ADDR+4 [01H, 4]		// attocode memory
 CTRL+3 [01H, 4]		// write new address
 DATA [TEXT]
 EXE
 
 DATA+24 1(8)	// prepare for data exchange
 
 LOOP: 
 
 // cleanup after jump
 CTRL+7 0
 ADDR+4 [05H, 4]		// out register
 CTRL+3 [00H, 4]		// stop the output
 EXE
 
 // Write the character
 ADDR+4 [01H, 4]		// attocode memory
 CTRL+3 [03H, 4]		// output addressed data
 EXE
 
 ADDR+4 [0BH, 4]		// address text display
 CTRL+3 [03H, 4]		// write character and increment address
 EXE
 
 // Maintain the loop if end of string wasn't reached yet
 
 ADDR+4 [01H, 4]		// address attocode memory
 CTRL+3 [07H, 4]		// move to the next element
 EXE
 
 ADDR+4 [02H, 4]		// address TEMP register
 CTRL+3 [03H, 4]		// write value without mask from the databus
 EXE
 
 ADDR+4 [01H, 4]		// attocode memory
 CTRL+3 [00H, 4]		// stop data output
 EXE
 
 ADDR+4 [04H, 4]		// address ALU
 CTRL [29H, 7]		// ZeroSet
 DATA [ENDLOOP]
 EXE
 CTRL [2AH, 7]		// NotZeroSet
 DATA [LOOP]
 EXE
 
 CTRL 000	// clear three MSB
 
 DATA+24 1(8)	// prepare for data exchange
 
 ADDR+4 [05H, 4]		// OUT register
 CTRL+3 [01H, 4]		// output its contents
 EXE
 
 ADDR+4 [00H, 4]	// aPC
 CTRL+3 [01H, 4]	// write new address from the databus
 EXE
 
 ENDLOOP:
 
 // cleanup after jump
 CTRL+7 0
 ADDR+4 [05H, 4]		// out register
 CTRL+3 [00H, 4]		// stop the output
 EXE
 
 // infinite loop to stop the program from executing following (nonexistent - gibberish) code
 AJMP [INFLOOP, 15]
 INFLOOP:
 AJMP+15(2) !
 
 text:
 "Hello world!" $00
=== MOV mem, mem Example ===
 /*
 Implementation of MOV mem32, mem32 instruction in the AttoASM
 
 This code is not fully optimized for sake of readibility, it
 can be further optimized to execute faster and also be smaller
 
 Following code assumes, that programmer has already decoded
 addresses of both memory locations and stored them in the
 register memory unit on address 0x03 in registers he called
 TMP0 and TMP1
 */
 EXE { CTRL+7(2) ! } // execute the command - Symbol/Macro, equivalent to sequence of CTRL+7 1, CTRL+7 0
 
 CTRL 0(8) // clear control bus from any previous codes codes
 ADDR 0(8) // clear the address as well
 DATA 0(32) // data as well 
 
 ADDR+4 0011 // address register memory
 DATA+27 0001 // move address of the TMP1 register the register memory on the data bus
 CTRL+6 1 // prepare command code to control bus, which will tell currently addressed device - spec. data memory to read value on data bus and store it in its own addressation register
 CTRL+7 1 // by activating most significant bit on the control bus, tell addressed device to read the instruction code on the control bus and thus address TMP1 register
 CTRL+7 0 // don't forget to set it back to zero afterwards
 DATA 1(32) // set all wires of data bus to 1, so it won't interrupt data outputed by special memory
 CTRL+5 1 // (in combination with previous CTRL+6 1 forms code 11) prepare instruction code, which will tell special data memory to read value of addressed location and output it on the data bus
 CTRL+7 1 // activate control instruction (after this, value of TMP1 will be on the data bus)
 CTRL+7 0 // deactivate it again
 ADDR+4 0111 // address program/data memory
 CTRL+5 01 // prepare command code, which will tell program/data memory to read address from data bus and address appropriate cell (source location)
 EXE // macro for CTRL+7 1 CTRL+7 0, after this, source location is addressed in program/data memory
 CTRL+5 11 // prepare command code, which will tell program/data memory to ouput value at addressed cell to the data bus
 EXE // value of source address is now at data bus (however, still mixed with the address from TMP1)
 ADDR+4 0011 // address special data memory again
 CTRL+5 00 // erase previous control instruction, this forms zero instruction, which tells the special data memory to disconnect from data bus (high impedance mode) and thus stop disturbing the value on data bus from source location
 EXE
 ADDR+4 0010 // address standalone TEMP register
 CTRL+5 01 // prepare instruction code which will tell the TEMP register to store value on the data bus in itself
 EXE // TEMP now contains the source value
 ADDR+4 0011 // address register memory again
 DATA 0(30)10 // put address of TMP2 register in register memory on the data bus (TMP2 contains target location)
 CTRL+5 01 // prepare command code which will tell register memory to address location with address on the data bus
 EXE
 CTRL+5 1 // (in combination with previous command code 1 forms code 11) prepare command code, which will tell special data memory to read value of addressed location and output it on the data bus
 EXE
 ADDR 0111 // address program/data memory
 CTRL+5 0 // (clear this bit, changing 11 to 01) prepare instruction code, which will tell program/data memory to read address from data bus and address appropriate cell (target location) and by changing the instruction code, this will also stop it outputing value of source address on the data bus
 EXE // target location is now addressed
 ADDR 0010 // address standalone TEMP again
 CTRL+5 10 // prepare instructoin code, which will instruct standalone TEMP to output its value (which is source value) on the data bus
 EXE
 ADDR 0011 // address register memory
 CTRL+6 0 // erase control instruction, to stop special data memory from outputting value on the data bus
 EXE // data bus now contains only the source value from TEMP
 ADDR 0111 // address program/data memory again
 CTRL+4 100 // prepare instruction code, which will tell program/data memory to read value from data bus and store it at addressed location
 EXE // target location now contains value of source location, MOV operation is complete (some cleanup may follow as well as jump to start decoding another instruction from program/data memory)
=== Syntax Overview ===
AttoASM supports 4 elementary instructions, which can be written by following symbols:
 0 fall
 1 rise
 ! invert
 | halt (optional)
 - skip (pseudo instruction)
Each statement starts with a number from 0 to 63 which determines the address of the first bit, followed by at least one of the symbols representing the instructions. Each consecutive instruction applies to the following bit of the bus. It's also possible to convert an integer or single precision floating point number to a series of instructions using the square brackets statement.
For simplification, four symbols are predefined, each one holding starting bit of one of the four logical buses:
 ADDR = 0 start of the address bus
 CTRL = 8 start of the control bus
 DATA = 16 start of the data bus
 AJMP = 48 start of the Quick aJump bus
Here are some examples of valid statements in AttoASM:
 CTRL+2 0001
 DATA 110-11001 // is same as:
 DATA 110 DATA+4 1101
 ADDR+4 !01
 DATA [15550] // write number 15550 to the data bus
 ADDR [0CH,8,0]
AttoASM also supports definition of symbols. Symbol basically contains any valid piece of AttoASM code, which is placed at every location, where the symbol is used, as is, with the exception of local symbols inside a symbol, which are made unique for every usage of the symbol by generating an unique name. Symbol can't be used prior its definition, with the exception of labels.
It's also possible to redefine symbol - new definition is valid from the point of redefinition. Redefined version is applied also to any subsequent usages of symbols, that contain usage of the redefined symbol and thus allow to pass arguments or whole pieces of code to the other symbols.
Labels are special form of symbols, when they're defined, they hold an integer number with the address of the instruction immediately following the symbol. They can be used like any other symbol.
Infinite loop example:
 EXE { CTRL+7(2) ! } // symbol to execute the command
 ADDR 0(8) // address aPC
 CTRL 0(6)01 // prepare command code to write new address to the aPC
 DATA+11 [Somelabel, 20] //write the address of the label to the data bus
 Somelabel:
 EXE // execute the command and thus cause jump back to Somelabel
==Trivia==
The WPU concept was originally concieved by Frooxius, who is now most well known for Neos.
==External resources==
* 
Category:Languages
Category:2011
Category:Implemented
Category:Self-modifying
Category:Low-level