PASM
PASM (PythonshellDebugwindow's Assembly) is an assembly language for a hypothetical machine, the P-Machine. It was created by User:PythonshellDebugwindow in December 2020.
The P-Machine
The P-Machine uses—or rather, would use—65536 (2^16) bits of ROM, the same as 8192 bytes or 64kb, and 256 bits of display memory (16x16 pixel screen). It also uses 6 registers (ba, bb, na, nb, ya, yb), a 1-bit conditional flag, and a call stack. It uses a bus width of 1 bit.
Memory
PASM uses the same memory as the P-Machine: 65536 bits of ROM, 256 bits of display memory, 6 registers, a conditional flag, and a call stack.
ROM
The P-Machine, and by extension PASM, uses 65536 bits of ROM.
Display memory
The P-Machine has a 16x16 pixel black-and-white (1-bit colour) screen, and as such has 256 bits of display memory. It also has a display pointer, which can point to one pixel on the screen at a time.
Registers
PASM has access to 6 registers: ba, bb, na, nb, ya, yb. Registers whose names start with b store 1 bit, n registers store 1 nybble, and y registers store 1 byte.
Conditional flag
The conditional flag a 1-bit flag.
Call stack
The P-Machine also uses a call stack of unbounded size.
Syntax
PASM code is grouped into sections. Sections can be declared by writing .[name], where [name] is the (alphanumeric) name of the section. The .ent section is the entry point of the program. A section lasts until another section is declared. Within sections, instructions and labels can be written. Instruction arguments are separated by commas. Labels are delared by writing [name]: before an instruction, and act partially like sections, except that they don't affect the call stack (see #Sections vs. labels).
An unlimited amount of instructions can be put within sections.
In instruction arguments, [hex]h is a literal case-insensitive hexadecimal number, where [hex] is the hexadecimal number; ROM can be referenced in programs by writing &[addr]h, where [addr] is the address in hexadecimal; display memory, the display pointer, and the condition flag can not be referenced directly in programs; registers can be referenced in programs by writing %[reg], where [reg] is the name of a register; and @[name] represents the section or label called [name].
; declares a comment until the end of a line. Spaces and tabs are ignored in programs.
Sections vs. labels
Jumping to a section pushes the location jumped to onto the call stack; jumping to a label does not.
List of instructions
| Instruction | Arguments | Effect |
|---|---|---|
| Memory manipulation | ||
mov |
a, b |
Sets the memory at a to b
|
| Comparison | ||
cmp |
a, b |
Sets the conditional flag to 1 if a and b are equal, and does nothing otherwise
|
| Mathematical and logical operations | ||
add |
a, b |
Adds b to a in place, which must not be a literal value
|
sub |
a, b |
Subtracts b from a in place, which must not be a literal value
|
mul |
a, b |
Multiplies b by a into a, which must not be a literal value
|
div |
a, b |
Floor-divides a by b into a, which must not be a literal value
|
| Control flow | ||
jmp |
a |
Jumps to a
|
jz |
a |
Jumps to a if the conditional flag is set to 0
|
jnz |
a |
Jumps to a if the conditional flag is set to 1
|
hlt |
a |
Halts the program with exit status a (zero is success, all other values are failure)
|
nop |
None | Do nothing (nop) |
| Display-related commands | ||
dofft |
x, y |
Sets the display pointer to (x,y)
|
din |
a |
Read the display at the display pointer and write it to a, which must not be a literal value
|
dout |
a |
Write a to the display at the display pointer
|
Examples
Clear the screen to white
.ent
mov %na,0h
x: mov %nb,0h
dofft %na,%nb
y: dout 0h
add %nb,1h
cmp %nb,fh
jz @y
add %na,1h
cmp %na,fh
jz @x
Truth-machine
Takes the top-left pixel of the screen as input (white is 0, black is 1). Sets the bottom-right pixel to 0 on input 0, infinitely toggles it on input 1.
.ent
dofft 0h, 0h
din %na
cmp %na,1h
dofft fh, fh
inf: dout %na
dout 0h
jnz @inf