Pit

Pit is an Esoteric programming language by David Catt (user:david.werecat) which is designed to be extremely low level.

About The Language
Pit is a language which was supposed to be so low level, it would make most other esoteric languages look like BASIC. It could be a lot more low level (since all devices and memory are pre-initialized and there are no "real" CPU control instructions), but the author decided not to be that sadistic. Source files can be coded in a script format similar to assembler or can be written as a bytecode file using a hex editor. The textual script format must assembled into bytecode before running.

Language Basics
Pit bytecode is run in a virtual machine that is hosted by the interpreter. The virtual machine has three major parts: the CPU, the memory controller and the device hub. The CPU executes the program code sequentially until the end of codespace is reached or an  instruction is encountered. The memory controller hosts the VM's memory. All memory in Pit is bitwise. The memory is split into three parts: MemorySpace, CodeSpace and CacheSpace. CodeSpace is a section of memory stored directly before MemorySpace. It contains the program code and can be reached by decrementing the memory pointer until it goes below zero. MemorySpace is where the memory available to the program is stored. MemorySpace is indexed by a pointer bounded by the size of the VM's memory (32mb in the reference implementation). The memory available to the VM can theoretically be infinite, however. CacheSpace is a 16 bit chunk of memory separate from the other memory spaces. The CPU can only perform operations on memory in CacheSpace, although can move memory between CacheSpace and MemorySpace. The final part of the Pit Virtual Machine is the device hub. The device hub maintains a packet queue of messages from the various virtual hardware devices and also acts as an interface to send messages to all attached devices. The device hub automatically sets up, initializes and shuts down all devices.

Pit Assembly Language
Most Pit coding can be done it a more human readable assembly language ("*.pit" files). Each line of source code can either be blank, a comment or a command. To create a comment in the Pit assembly language, prefix the line with a tilde (~). Commands are usually a three letter instruction code followed by a space then followed by one hexadecimal character as a parameter for the command (eg. ).  Every command must have a parameter, even if it is not used. To assemble a Pit assembly language script, call the implementation with the argument  followed by the source file path and the destination file path of where to write the assembled binary.

Pit Bytecode
All Pit programs must be in their bytecode form in order to run. A Pit bytecode binary consists of several 8 bit instructions. Each 8 bit instruction is divided into two parts: the first 4 bits for the opcode, and the last 4 bits for the parameter. As stated previously, the binary file is loaded into memory before MemorySpace and is executed from there.

Pit Instructions
Pit accepts the following instructions:

Devices and Packet Format
Pit supports up to 8 different devices with the default device hub. Currently, the following devices are defined:
 * 000 - Console
 * 001 - Beep

The device hub communicates with the devices using a standard packet format: {1 bit StartOfPacket, always 1}{3 bits DEVICE_ID}{n tuples DATA}{1 bit EndOfPacket, always 0}

For example, to encode a packet with the message 0011 to device 101, the following packet would be sent: 1 101 10 10 11 11 0

A tuple is two bits, the first representing the packet type (0 for EOP, 1 for DATA), the second being the packet data. The second bit is only included if the first bit is 1.

The following packets are supported:

Note that the size is the size of the data, not the size of the packet.

Programming Help
Since Pit defines no methods of logical operators, math or algorithms there is a page to help with basic programming in Pit. Alternatively, you could do it the fun way and figure it out for yourself.

CAT Program
~The main loop PSH 1 ~Wait for a 1 from the device hub PSH 1 ~Wait for 1ms to keep CPU usage low HLT 0 ~Read a bit from the device hub RCV 0 SKP 0 JMP 1 ~Check for a device_id of 0 (console) ~Set cache(0) to 0 NOT 0 ~Read each bit and update accordingly RCV 1 SKP 1 JMP 0 ~Set the cache(0) to 1 SKP 0 NOT 0 FLG 0 RCV 1 SKP 1 JMP 0 ~Set the cache(0) to 1 SKP 0 NOT 0 FLG 0 RCV 1 SKP 1 JMP 0 ~Set the cache(0) to 1 SKP 0 NOT 0 FLG 0 ~If it wasn't 0, read to the end of the packet and continue waiting for events SKP 0 JMP 0 PSH 1 RCV 2 ~If the bit is a 0, it is EOM, so no more bits NOT 2 SKP 2 RCV 3 SKP 2 JMP 1 POP 1 FLG 0 NOT 0 ~If cache(0) is 0, the device_id was 0 (console), so write the keyval to the console SKP 0 JMP 0 ~Check for EOF (null packet) and exit if EOF RCV 3 SKP 3 POP 1 SKP 3 OFF 0 ~Write packet header for the console (device_id 0) ~Set cache(2) to 1 SKP 2 NOT 2 SND 2 NOT 2 SND 2 SND 2 SND 2 ~Copy the start of the packet SND 3 RCV 3 SND 3 ~Copy packet until EOM PSH 1 RCV 2 SND 2 ~If the bit is a 0, it is EOM, so no more bits NOT 2 SKP 2 RCV 3 SKP 2 SND 3 SKP 2 JMP 1 POP 1 FLG 0 JMP 1 ~Cleanup POP 1 OFF 0

Hello, world!
NOT 1 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 0 SND 1 SND 0 SND 0 SND 0 SND 1 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 1 NOT 2 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 SND 2 SND 1 NOT 2 SND 2 SND 0 OFF 0

Additional Help
If anything isn't clear, there's a bug in the reference implementation, something could be improved, etc... feel free to write a comment in the talk page and I'll get around to it as soon as I can.

External resources
Reference implementation and sample programs (needs .net framework)