-
Notifications
You must be signed in to change notification settings - Fork 4
PMAS
Identifiers can start with _ or alphabetic character.
Labels cannot have space in front of the name. Instructions do need space prepended. Directives start with a . and does not matter if there is space prepended.
Since PMAS is a 2-stage assembler, labels can be referenced before they are defined.
(Instruction) operands and (macro) parameters can be separated with comma's. Any whitespace between the parameters is discarded except when quoted.
Double quotes (") can be used for strings. Single quotes (') for characters.
Escape sequences can be used. e.g. to create new-line characters.
; comment # comment
Operators are special characters that operate on values during assembly.
The table below shows all operators in their respective order of priority:
| Operator(s) | Operation(s) |
|---|---|
| ( ) | Evaluates everything between braces. Use these to deviate from normal priority. |
| ! ~ - + | Unary operations: Logical NOT, bit-wise invert, negative, positive. |
|
Multiplication, division, modulo. |
| + - | Add, subtract. |
| >> << | Shift. |
| > < <= >= | Compare relative. |
| Compare exact. | |
| & | Bit-wise AND. |
| ^ | Bit-wise XOR. |
| ¦ | Bit-wise OR. |
| && | Logical AND. |
| ¦¦ | Logical OR. |
Labels define a name with the current address. Local labels can be created by using '_' prefix.
DoSomething2: _loop: jmpw _loop ; force long jump with 'W' suffix
mov a ,170 ; decimal mov a , 0b10101010 ; binary (% is no more) mov a, $AA ; hex mov a, 0xAA ; hex mov a, @AA ; hex (deprecated) mov a, 'A' ; ascii value mov x, 'x1' ; 16-bit ascii value mov a, '\x40' ; hex
Symbols include: variables, labels. They are global and can be used from the point of declaration.
.[[#equ|equ]] wow1 0xAA ; equ's are handy for register definitions and precalculations .equ wow2, wow1 .db wow2 ; variables should be defined before using .equ cool "ascii string" ; it can even handle strings! .equ cool0 cool+"\0" ; string concatenation .equ cool1 "blah"+1 ; results in "blah1" .[[#set|set]] cool2 123 ; equivalent of set .[[#unset|unset]] cool2 ; unsets a symbol
The current address pointer.
addr_example: jmpw [[#.|.]] ; loop to current address
.incbin file.bin
Include assembly file. First, it tries a relative path, then the PMAS executable path.
.include cpu/pm.s .include "wow.inc"
invalid directive error (default = 1)
.option [[#directive|directive]] 0
range checking of immediate values (default = 0)
.option [[#range|range]] 0
start address of output file (default = 0)
.option [[#base|base]] 0
jumps to local labels default to short jumps? (default = 1)
.option [[#localjump|localjump]] 0
jumps to non-local labels and without suffix default to far jumps? (default = 1)
.option [[#farjump|farjump]] 0
- NOT WORKING YET* non-jumps without B or W suffix default to word? (default = 0)
;.option [[#word|word]] 1
byte to fill uninitialized data with (default = 0xFF)
.option [[#fill|fill]] 0xAA
Reset the current assembly address to the specified value. Use reloc for a temporary change. .org 0x2100 ; set current assemble address.
Re-align the current address on a multiple of the give number of bytes. .align 8 ; align memory (for tile graphics etc.)
Starts/ends an address relocation. The __addr pointer will temporarily change while retaining output address. In combination with .ds you can easily describe memory structures.
temp: .[[#db|db]] 123 ; an initialization loop can be used to copy variables to RAM .[[#endreloc|endreloc]] data_end:
mov x, 0x1800 mov b, [x+Record_name_len] mov l, Record_name mov a, [x+l]
Strings can be passed to the assembler parser directly. Note that you can use macro's for most things instead.
.[[#parse|parse]] "label"+1+":" ; parse label .parse " nop" ; parse instruction
The main source of power of PMAS is the macro directive.
With this, you can insert a piece of code template with parameters specific to each call.
The '_' prefix character is replaced with a unique macro ID and can be used for local macro labels.
A parameter name starting with $ will be converted to a string. You could perhaps also use ""+param.
.equ a_number2 a_number * 2 .db a_string, a_number .dw a_number2 .if (a_string == "hello" && a_string2 == "world" && a_number == 123 && a_number2 == 246) .printf "It works :)\n" .else .printf "NOT WORKING!\n" .endif _local_label: .[[#endm|endm]] kewl hello, "world", 123 ; macro call .[[#rept|rept]] 3 ; repeat loop nop .[[#endr|endr]]
Output C-like formatted text to stdout while assembling.
.[[#printf|printf]] "I'm at %06X. 1+1=%u\n", ., (1+1) ; formatted output or current address
.[[#exit|exit]] ; end processing of all files (results in an error)
.[[#end|end]] ; end processing current file
bytes
.db 1,2,3,4 .[[#db|db]] cool0, 0, "\"\r\n\t\x55\\\0", # strings are byte arrays
words (16 bit)
.[[#dw|dw]] 0x0201,0x0403
double-words (32 bits)
.[[#dd|dd]] 0x04030201
space
.[[#ds|ds]] 100 ; reserve 100 bytes, fill with .option fill .ds 100, 0xAA ; reserve 100 bytes, fill with 0xAA
A condition is true when non-zero. Boolean operators return 0 or 1.
.[[#if|if]] 1==1 mov x, -123 .[[#elsif|elsif]] (2==2) this assembler rules ! .[[#else|else]] this is a stupid way to use comments :) .[[#endif|endif]]