Skip to content
darkfader edited this page Jun 21, 2012 · 1 revision

Table of Contents

Basics

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.

Comments

 ;			comment
 #			comment

Operators

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

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
 

Operands

 	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

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

Directives

incbin

 .incbin file.bin

include

Include assembly file. First, it tries a relative path, then the PMAS executable path.

 .include cpu/pm.s
 .include "wow.inc"

option

directive

invalid directive error (default = 1)

 .option	[[#directive|directive]]	0

range

range checking of immediate values (default = 0)

 .option	[[#range|range]]		0

base

start address of output file (default = 0)

 .option	[[#base|base]]		0

localjump

jumps to local labels default to short jumps? (default = 1)

 .option [[#localjump|localjump]]	0

farjump

jumps to non-local labels and without suffix default to far jumps? (default = 1)

 .option [[#farjump|farjump]]		0

word

  • NOT WORKING YET* non-jumps without B or W suffix default to word? (default = 0)
 ;.option [[#word|word]]		1

fill

byte to fill uninitialized data with (default = 0xFF)

 .option [[#fill|fill]]		0xAA

org

Reset the current assembly address to the specified value. Use reloc for a temporary change. .org 0x2100 ; set current assemble address.

align

Re-align the current address on a multiple of the give number of bytes. .align 8 ; align memory (for tile graphics etc.)

reloc

endreloc

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]

parse

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
 

macro

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]]
 

printf

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|exit]]								; end processing of all files (results in an error)

end

 	.[[#end|end]]								; end processing current file

Data directives

db

bytes

 .db			1,2,3,4
  	.[[#db|db]]		cool0, 0, "\"\r\n\t\x55\\\0",		# strings are byte arrays

dw

words (16 bit)

 	.[[#dw|dw]]		0x0201,0x0403

dd

double-words (32 bits)

 .[[#dd|dd]]			0x04030201

ds

space

 	.[[#ds|ds]]		100							; reserve 100 bytes, fill with .option fill
 	.ds		100, 0xAA					; reserve 100 bytes, fill with 0xAA

Condition directives

A condition is true when non-zero. Boolean operators return 0 or 1.

if

elsif

endif

 	.[[#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]]