Skip to content

TOON Language Overview

Cabintech edited this page Jul 10, 2026 · 18 revisions

Content

Target Of Operations Notation (TOON)

The FXCoreMP macro processor enables an alternative assembler language syntax "TOON" that is more expressive, simplifies common operations, and makes it easier to understand the sequence of operations and branching that makes up an FXCore program.

The TOON syntax can be freely mixed with regular FXCore assembler language syntax, so it can be used exclusively, sparsely, or not at all. The macro processor will translate all TOON statements into valid FXCore assembler.

TOON processing is a separate operation (from macro expansion) on the source code. TOON syntax can be used with or without macros, and macros can be used with or without TOON statements. By default TOON translation is run as the last step of the macro processor, but it can also be run as a stand alone tool.

We found that re-formatting our existing FXCore assembly code into TOON statements has improved our ability to modify, maintain, and develop new code features with fewer errors and less time consulting the FXCore instruction set documentation. Data movement and conditional branching become more apparent which makes the code easier to understand (especially when coming back to FXCore development after being away from it for a while).

As of V1.1.2 the processor supports a 'reverse' translation mode to automatically convert existing FXCore assembler statements into the TOON syntax. This can greatly speed the conversion of existing projects and allow a quick assessment of the TOON syntax on your own source code.

Target of an instruction

The original goal of TOON (and from which it derives its name) was to make the assembly language more explicit about the target of machine operations. The FXCore architecture is "accumulator-centric", most operations on data result in an implicit assignment of the results to the ACC32 register. For developers not working in this style on a regular basis, it can be difficult to get used to. It's like working in a high level language that has only one writable variable for expressions - instead of writing x = y + z you have to write two statements, acc = y + z followed by x = acc. A lot of FXCore code is moving data in and out of the ACC32 register.

This accumulator-centric programming style is made even more difficult because this accumulator side effect is not evident in the assembler statement. For example:

xori r8,0x0F

It might be assumed by a casual reader that after this operation the value of R8 would have been XOR'ed with 0x0F. But that is not the case, R8 remains unchanged and the result of the XOR is written to the accumulator (ACC32). This is not uncommon in machine architectures but the assembly language does not indicate the target of the operation. To know that, the programmer must be either very familiar with the machine instructions, or constantly referencing the documentation to know what is the target of an operation, and sometimes the ordering of the operands.

TOON seeks to make the target of operations explicit so reading source code is more self-explanatory and unambiguous. The TOON syntax for the above statement would be:

acc32 = r8 xor 0x0F

This makes it clear that the result of this operation is placed in (assigned to) the ACC32 register, and by placing the opcode (mnemonic) between the operands the statement is in a more natural language form "R8 is XOR'ed with 0x0F and assigned to ACC32". This reads more like a high level computer language and the operation and results can be fully understood without consulting the details of the xor machine instruction.

Note

The experienced FXCore programer will notice that the TOON statement appears to be incorrect because it is using the xor instruction when the right-hand operand is an immediate (constant) value - the xori instruction would be expected. The TOON processor analyizes the operand types and infers the correct instruction. TOON will generate the xori instruction for the above assignment. See the syntax reference for other instructions that can be inferred.

The TOON processor will validate that the target of such operation assignment statements are valid for the operation being performed. E.g. the XOR operation can only target the 32-bit accumulator, so if anything other then acc32 appears as the target of that instruction, an error will be flagged.

Because many FXCore instructions (implicitly) target ACC32 it may seem tedious and unnecessary to write acc32 = ... over and over in the source code. It does however allow many operations to be written in familiar programming assignment form and has many benefits for readability of the program source.

Since its inception, TOON has expanded to improve the readability of many FXCore assembly instructions by recasting them into forms similar to high level languages. Initially TOON was a 1:1 translator, each TOON statement was translated into exactly one FXCore assembly instruction. As TOON has evolved this is no longer true, some TOON statements generate more than one instructions, and some may generate none at all or non-executable assembler directives and labels. Although the syntax may be easier to understand, a through understanding of FXCore instructions is still required.

Readability of TOON statements

TOON formated code can be (subjectively) easier to read and understand-at-a-glance. TOON seeks to make the semantics of assembler code expicit, clear, and intuitive for progammers. Traditional assembler code uses the same basic format for all statements no matter what they do:

opcode operand1,operand2

There is no visual distinction between assignments, data operations, conditional branches, etc. In higher level languages those constructs have very different syntax. This helps with intuitive understanding of the code structure. Not having that syntactic visual aid makes assembler harder to read and understand. (For more on the concepts of 'high level assembler' see the Backgound section).

For example we often want to scan a block of code and know where (or if) a particular register is being modified. Scanning traditional assembler code requires careful reading to find where registers are being updated (explicitly in the list of operands, or implicitly by the definition of the instruction).

Consider the following assembler code:

.rn temp  r0
.rn temp1 r1
.rn scaleFactorMin r2
.rn scaleFactorMax r3
.rn scaleFactorRange r4
.equ delayLen 512
.mem delaymem0 delayLen
.mem delaymem1 delayLen

1.  cpy_cs      acc32,in0
2.  wrdel       delaymem0,acc32
3.  cpy_cs      acc32,in1
4.  wrdel       delaymem1,acc32
5.  cpy_cs      temp,pot0_smth
6.  wrdld       temp1,delayLen
7.  multrr      temp,temp1
8.  cpy_cc      scaleFactorMin,acc32
9.  cpy_cs      temp,pot1_smth
10. wrdld       temp1,delayLen
11. multrr      temp,temp1
12. cpy_cc      scaleFactorMax,acc32
13. subs        scaleFactorMax,scaleFactorMin
14. jgez        acc32,save_range
15. cpy_cc      temp,scaleFactorMax
16. cpy_cc      scaleFactorMax,scaleFactorMin
17. cpy_cc      scaleFactorMin,temp
18. abs	        acc32
19. save_range:
20. cpy_cc      scaleFactorRange,acc32

Is the register named scaleFactorMax modified by this code? If so, where? To answer those basic questions require some careful reading of the code. The symbol scaleFactorMax appears in several places, but do any of those update it's value? Even finding that symbol in all the lists of operands takes some careful reading.

That same block of code in TOON format:

.rn temp  r0
.rn temp1 r1
.rn scaleFactorMin r2
.rn scaleFactorMax r3
.rn scaleFactorRange r4
.equ delayLen 512
.mem delaymem0 delayLen
.mem delaymem1 delayLen

1.  acc32          = in0
2.  (delaymem0)    = acc32
3.  acc32          = in1
4.  (delaymem1)    = acc32
5.  temp           = pot0_smth 
6.  temp1.u        = delayLen
7.  acc32          = temp mult temp1
8.  scaleFactorMin = acc32
9.  temp           = pot1_smth
10. temp1.u        = delayLen
11. acc32          = temp mult temp1
12. scaleFactorMax = acc32
13. acc32          = scaleFactorMax subs scaleFactorMin
14. if acc32 < 0 then
15.     temp           = scaleFactorMax
16.     scaleFactorMax = scaleFactorMin
17.     scaleFactorMin = temp 
18.     acc32          = abs acc32
19. endif
20. scaleFactorRange = acc32

This is recognizable as a series of assignment and conditional branching statements. Just scan the left column and where you find `scaleFactorMax' you know that it is modified by that instruction (lines 12 and 16 are easy to spot).

The example also show some other features of the TOON syntax.

  • The assignment in line 1 is from an SFR (IN0) to a core register (ACC32). TOON determins that the assembler instruction cpy_cs is required and generates the approprate assembler statement. See Assignment Statements section below. The TOON assignment statement has additional capabilities:
    • In line 4, ACC32 is written to delay memory by an ''indirect'' constant address. Delay memory addressing is indicated by the parens.
    • In line 6, a 16 bit constant value is assigned to the upper part of register temp1. The ".U" postfix makes the semantics of this special assignment clear.
  • The multiply on line 7 uses MULT which is not an FXCore instruction but is understood by TOON to implement a multiply operation on the 2 operands. TOON infers the proper FXCore instruction and generates the proper assembly instruction (multrr in this case because both operands are core registers). There are several such generic TOON operators to reduce the distracting detail in the code. See the TOON Syntax Reference for other inferred instructions.
  • The conditional branch on line 14 is written as a familiar "if-then" statement block. (See Conditional Branching section below).

Many of these features are described in the following sections.

Assignment statements

The backbone of all computer languages is data movement, or 'copy/load/store' instructions. The well understood syntax of using the = symbol to denote assignment is common in many languages. However in FXCore assembler (and most assembler languages), copy instructions adhere to the rigid <opcode> <operand>,<operand> format:

cpy_cm r8,mr41

TOON makes special provisions for copy operations, expressing them in more familiar assignment syntax. The above would be written in TOON syntax as simply:

r8 = mr41

The mnemonic is removed from the syntax all together to make an instantly more readable statement. The developer does not have to consider all the cpy_XX variations and think carefully about the order of the operands (which has great significance for the copy instructions). Anyone versed in software development of any kind will immediately understand the target is on the left, and the source is on the right of the = symbol.

The TOON processor interprets the assignment statement and infers the correct instruction from the type of the source and destination operands.

All the cpy_XX mnemonics can be replaced with TOON assignment statements even if the operands are symbolic:

.rn    delayTime    r12
$macro sampleWindow mr41

delayTime = $sampleWindow

The TOON processor will generate the proper cpy_cm instruction in this example.

Delay Memory Assignments

TOON provides special syntax for indirect copy operations to/from delay memory. Parens are used indicate indirect delay memory operations such as:

(r0) = acc32

This assignment writes the contents of the register ACC32 to the delay memory location contained in R0. E.g. R0 is an indirect reference to a delay memory location. TOON will generate a wrdelx instruction for this assigment. TOON supports all the FXCore delay addressing modes:

  • Immediate load Rx = (addr) or store (addr) = Rx
  • Indirect load Rx = (Ry) or store (Rx) = Ry
  • Absolute (no AGU) indirect load Rx = #(Ry) or store #(Rx) = Ry

Memory Register Assignments

In addition to the simple assignment of memory registers to/from core registers, e.g.

mr101 = acc32

The FXCore also supports indirect reading (not writing) of memory registers. This is represented in TOON in a similar way to indirect delay memory, but using square brackets instead of parens:

r5 = [r1]

This loads the memory register addressed by the content of R1 into register R5. Note that the reverse is not supported:

[r5] = r1 ; NOT supported by FXCore

64/32 Bit Assignments

FXCore also provides instructions for transferring 32 bit words between core registers and the upper and lower half of the 64 bit accumulator (ACC64). Rather than lookup those nmemonics, TOON assignment statements can generate the proper assembler code from easy to write assignment statements such as:

acc64.u = r5

The semantics are clear in the statement, the content of R5 is written to the upper half of ACC64. Likewise simple assignements transfer data the other way:

acc32 = acc64.l

See the Syntax Reference for all the 64 bit assignment statements.

32-Bit Math, Shift, Logic functions

Data manipulation makes up the bulk of most FXCore assembler programs, so improving the intuitive reading and understanding of the semantics from the source code is very useful.

TOON provides a more readable and intuitive syntax for the FXCore 32-bit data operations such as math functions, bitwise functions, and logic functions. These statements are written as assignments with functional expressions because they both modify data and move (copy) it to a specific location (ACC32).

For example, to perform an addition the assembler statement would be of the form "add a,b". TOON changes this implicit assignment of ACC32 into a more familiar and intuitive high level syntax of "acc32 = a + b". TOON recognizes a number of common math, shift, and logic symbols and infers the proper FXCore mnemonic (see the TOON syntax reference page). It is also possible to use the mnemonic in the TOON expression if that is preferred, e.g. "acc32 = a add b".

acc32 = r4 ^ r9      ; R4 is XORed with R9 and the result placed in ACC32
acc32 = acc32 sl r8  ; Correct instruction "SLR" will be inferred
acc32 = r0 + 0xF     ; Generates an add-immediate (ADDI) instruction

This syntax gives more of a high level programming feel to these instructions. The function between the 2 operands can be any of the FXCore 32-bit math or logic instruction mnemonics or any of the TOON symbols:

+   : Add (signed)
++  : Add (signed, saturated)
+u  : Add (unsigned)
-   : Subtract (signed, saturated)
--  : Subtract (signed, saturated)
-u  : Subtract (unsigned)
*   : Multiply (saturated)
**  : Multiply (saturated)
|   : Bitwise OR
&   : Bitwise AND
^   : Bitwise XOR
<<  : Shift left logical
<<< : Shift left arithmetic (saturated)
>>  : Shift right logical
>>> : Shift right arithmetic

For the math operators, the symbol is doubled to indicate a saturation operation, and has a "u" postfix to indicate an unsigned operation. Note the FXCore does not support all combinations of operators, sign, and saturation. For example there is no unsigned subtraction and there is no un-saturated multiplication. Example:

ACC32 = R1 +u R2 ; Unsigned addition of two registers

TOON extends some mnemonics to make them generic, and then generates a correct mnemonic by inferrence from the operand types. For example:

acc32 = acc32 sl r8  ; Correct instruction "SLR" will be inferred

This shows the "SL" instruction but the right side is a register so the correct mnemonic should be "SLR". TOON recognizes "SL" as a inferrable instruction and substitutes the correct mnemonic. The 32-bit data instructions that TOON can infer are:

OR
AND
XOR
SL
SR
MULT

See the Syntax Reference for all the 32 bit operation statements.

64-Bit Summation Operations

The FXcore has a number of instructions that accumulate (sum) results in the 64 bit accumulator. These instructions can be used in TOON statements with the same assignment-expression syntax as 32-Bit Operations. However, for source code clarity, a += assignment operator can be used as a reminder that the operation is not a straight assginment of the expression results, but it is also a summation (add) of the current ACC64 value. This type of syntax is common in high level languages as a shorthand for writing a = a + b. Many languags allow this to be written as a += b.

These statements are written as assignments with the target of ACC64. The += notation is optional, they can also be written with just the = symbol:

acc64 += R0 macrr R1
acc64 += R8 machri -0.7
acc64 = r8 macr -0.3

We recommend using the += symbol for the added clarity.

Note that the last statement uses a non-existant nmemonic macr. Similar to the 32 bit operations, some generic inferred functions are recognized by TOON and the proper FXCore instruction is generated by inferrence from the operands. In the case of the last statement above, TOON will generate the immediate instruction macri.

See the Syntax Reference for all the 64 bit operation statements.

Conditional Branching

Basic FXCore assembler syntax for branching uses the same syntax as all other statements making it difficult to quickly see and understand what code is conditionally executed.

TOON converts the cryptic test-and-branch assembler mnemonics into familiar high level language constructs like IF, GOTO, and IF-THEN-ELSE blocks using common conditional tests like =, !=, >, etc. This greatly improves the readability of the code. When used with indenting these constructs provide instant visibility of where code is conditionally executed. Conditional code blocks can be nested to any level.

For experienced programmers there is a cognitive challenge in assembler test-and-branch logic. In assembler, the code immediately following the test is executed when the condition is false. In high level languages the code following an IF statement is executed when the condition is true. For example:

Assembler Syntax                 TOON Syntax

jz acc32, label1                 if acc32 != 0 then
  wrdel delaymem, acc32            (delaymem) = acc32
  cpy_cc acc32, temp               acc32 = temp
  cpy_mc mr107, acc32              mr102 = acc32
label1:                          endif

In this example, a conditional block of code is executed when ACC32 not is zero, but in assembler syntax the condition is written as ACC32 equals zero. E.g. the condition indicates when to skip the block (take the branch) instead of when to execute it (do not branch). This inverted form of branch logic is just cognitive noise for programmers used to IF-THEN-ELSE style conditional execution. It requires a sort of mental inversion to understand the program flow.

When program logic requires multiple nested conditional execution paths, the branching logic and labeling can make it even harder to understand. TOON will automatically generate all the required branch logic and target labels to implement IF-THEN-ELSE style conditional execution to any level of nesting. For example, the following assembler code:

cpy_cc r6, temp
cpy_cs acc32,in0
wrdel delaymem0,acc32
cpy_cs acc32,in1
wrdel delaymem1,acc32
jnz temp, label2 
cpy_cs temp,pot0_smth
wrdld temp1,delayLen
multrr temp,temp1
jz acc32, label2
cpy_cc scaleFactorMax,scaleFactorMin
cpy_cc scaleFactorMin,temp
label1:
cpy_cs acc32,in1
wrdel delaymem1,acc32
cpy_cs temp,pot2_smth
label2:
abs acc32
cpy_cc scaleFactorRange,acc32

can be written in TOON as:

r6 = temp
acc32 = in0
(delaymem0)	= acc32
acc32 = in1
(delaymem1)	= acc32
if temp = 0 then
    temp = pot0_smth 
    temp1.u	= delayLen
    acc32 = temp mult temp1
    if r7 != 0 then
        temp = scaleFactorMax	
        scaleFactorMax = scaleFactorMin
    endif
    acc32 = 0
    (delaymem1) = acc32
endif
acc32 = abs acc32
scaleFactorRange = acc32

The TOON syntax for the conditional blocks of code are easy to see and there is no need to create unique labels for each branch.

In addition to the IF-THEN-ELSE blocks, TOON supports direct test-and-branch logic with a an IF-GOTO syntax that is made easier to read by using familiar boolean operators.The GOTO token in the IF statement is optional and can be omitted.

if r9 >=0 goto save_range
if acc32 = 0 goto alldone

The choice of condition operators is limited to those directly supported by FXCore branch instructions, so the only allowed operators are:

  • = 0 The register is zero
  • <> 0 or != 0 The regsiter is not equal to zero
  • >= 0 The register is greater than or equal to zero
  • <0 The register is less than zero (e.g.negative)
  • != acc32.sign The register does not have the same sign as ACC32

Using this familiar IF statement coding syntax makes it easy to spot key code branching points without lots of comments, blank lines, or indentation to visually highlight the code flow.

Inferred Instructions

For some instructions, the TOON process has the ability to infer the programmer's intent from the context and generate the correct code even when the programmer did not specify it precisely. As noted in some examples above, some instructions can be written generically and TOON will infer the proper opcode, for example:

acc32 = r0 add 6

This would appear to be invalid from the pure FXCore instruction set because addition of an immediate constant value must be done with the addi instruction. In TOON code, the add instruction is an inferred instruction and the TOON processor examines the context and based on the use of a constant as the right-hand operand, it generates the assembler code:

r0 addi 6

If the same TOON statement was written with a core register as the right operand:

acc32 = r0 add r12

then TOON will generate the code with the FXCore add instruction for 2 registers:

r0 add r12

Note that FXCore has both signed and unsigned ADD instructions so TOON may not correctly interpret the programmer's intent when using inferred instructions - in the case of the ADD instruction the inference always chooses unsigned operations. If (for example) a signed immediate ADD is required, then the exactly FXCore instruction must be specified:

acc32 = r0 addsi 0.6

Inferred Instructions in Macros

It can be particularly useful to used inferred instructions in macro definitions because it allows the macro to work with multiple types of arguments without any complicated conditional logic. For example, a macro defined like this:

$macro CALCX(inputA, inputB, outputC) ++
  acc32 = 0
  acc32 = acc32 or inputA
  acc32 = acc32 sl 4
  ...other calculations...
$endmacro

This macro can be invoked with its first argument being a constant or a register:

$CALCX(0x7F, r4, r0)
$CALCX(r1, r4, r0)

In either case, the first argument is OR'ed with ACC32 with the proper instruction. This can make macros more flexible.

All Pass Filter Instructions

FXCore implements all-pass filters using a pair of 2 instructions. It requires careful reading of the FXCore manual to use the instruction pair properly as some things are somewhat counter-intuitive and there are side effects not apparent from the assembler mnemonics. To support multiple address modes and coefficient sources there are 4 pairs of instructions for a total of 8 assembler mnemonics.

TOON simplifies all-pass filter coding by encapsulating all of the options in a single assignment statement. This assignment follows the TOON convention in that it fully expresses the target of the operation and all the sources. It also follows the convention of enclosing indirect addressing in parenthesis.

Note: It is highly recommended to read the FXCore Application Note #8 to understand the all-pass filter concepts. However that document does not describe how to code the filter instructions.

The general form of the TOON all-pass filter statement is:

ACC32,R15 = ACC32 ALLPASS <coeff>, <head>, <tail>

The left side of the assignment is ACC32 and R15, both of which are overwritten (thus are targets) of the all-pass filter instructions. Note that R15 is used as a temporary value, but since it is overwritten it appears on the left side of the assignment as a reminder that the value of this register is replaced by the operation.

The right side starts with ACC32 ALLPASS followed by a comma-separated list of the filter coefficient, the address of the head of the block, and the address of the tail of the block. The coefficient can be

  • a constant value such as 0.45, or
  • name of a CR which contains the coefficient value.

The head / tail addresses can be

  • constant values enclosed in parens denoting an indirect delay memory address, or
  • names of CR enclosed in parens denoting indirect addressing by values in the CRs, or
  • an MR that contains a single delay value (only one MR should be specified, it will be both the head and the tail)

Examples:

acc32,r15 = ac32 allpass 0.45, (membuff1), (membuff1#) ; Constant coeff and memory addresses

acc32,r15 = acc32 allpass r11, mr101 ; Filter a single value in a MR

acc32,r15 = acc32 allpass r11, (r0), (r1) ; Coeff in R11, memory addresses in R0 and R1

The TOON ALLPASS statement will generate both of the instructions required to implement the filter operation. The exact instructions generated is inferred by the types of the coefficient and types of head/tail addresses. Not all combinations of coefficient types and address types are allowed, see the TOON Syntax Reference for all possible forms.

Chorus Instruction

The FXCore chorus instruction (CHR) has some specific requirements for the use of R15 and how the sample depth must be set in that register. To simplify the use of this instruction, TOON provides a statement that encapsulates the loading of R15 and execution of the CHR instruction. This insures that R15 is loaded properly immediately before executing the chorus instruction. As with other assembler instructions, TOON also simplifies the syntax and makes the side effects (targets and sources) explicit.

The general form of the TOON chorus instruction is:
ACC32,R15 = CHORUS <depth>, LFO[0|1|2|3], [+|-]SIN|COS, (const-addr)

TOON will generate 2 instructions for each CHORUS statement. First, TOON will generate code to load the <depth> value into R15, then the CHR instruction is generated. In the special case of when depth is R15, no code is generated to load it and ,R15 is omitted from the left side of the assignment.

The <depth> value may be

  • a constant, in which case TOON generates code to load the 16-bit constant into the upper half of R15
  • a CR, in which case TOON generates code to copy the CR to R15. Note the CR must have the depth in the upper 16 bits.
  • an MR, in which case TOON generates the code to copy the MR to R15. Note the MR must have the depth in the upper 16 bits.
  • R15 in which case TOON does not generate any code to load R15, it is assumed R15 contains the depth in the upper 16 bits.

The LFOx value must be one of LFO0, LFO1, LFO2, LFO3 as defined by the FXCore instruction set documentation.

The 3rd value must be either SIN or COS and may optionally be prefixed with a + or - symbol. If no symbol is given then + is assumed.

The const-addr must be a delay memory address constant enclosed in parens.

Examples:

.mem membuff1 512

acc32,r15 = chorus 128, lfo1, -cos, (membuff1)

It may seem odd to see both ACC32 and R15 on the left side of this assignment, but this is a visual reminder that both of these registers will be overwritten (ACC32 with the chorus result, R15 with the <depth> value as required by the CHR instruction). If the depth is R15 then no code is generated to modify it, thus in that case R15 does not appear on the left side of the assignment.

Other Assembler Instructions

At this time there are some FXCore instructions for which no TOON syntax has been defined. These instructions should be written as FXCore assembler statements:

pitch
set

A future version may define a TOON syntax for these instructions.

Code Generation

In general the TOON processor translates TOON statements to FXCore assembler statements one-for-one (a few TOON statements generate multiple FXCore instructions). The goal is to improve the development experience and ease-of-understanding for FXCore assembler code, not to actually implement a higher level language. Even within the confines of assembler and the FXCore instruction set, TOON provides a (subjectively) better experience for software development.

If a TOON statement contains a comment using the line-comment delimiters ; or // then the generated assembler output line will preserve that comment. This can aid in debugging the resulting assembler code. Likewise, if a TOON statement uses a .rn renamed (symbolic) value, the generated code will also use that symbol and not its resolved value.

TOON will not attempt to process any text between block comment delimiters /* ... */ on a single line or when such comments span multiple lines.

By default TOON will include the oringal TOON statement text in generated assembler statements as an inline comment. This may be disabled with the --noannotate command line argument.

Standalone execution

By default the TOON translator runs as the last step of the macro processor (e.g. after all macros have been expanded). The TOON translator can also be run without the macro processor, see the Usage section of the Installation page.

Background

Since their inception in 1947 assembler languages have been cryptic and rigid in their syntax. Machine instructions are represented with short mnemonics and a statement format that is uniform with something like:

<label> <mnemonic> <op1>,<op2>

This was a reflection of the rigid nature of the underlying machine architecture where op codes and operands were encoded into binary words which became the program stream understood by the CPU. Early assembler languages were implemented on machines with limited processing and memory capacity, so highly structured and predictable syntax, and short symbols were a necessity.

Over time features were added to allow some symbolic representation (EQU statements) various 'macro' statements which allowed symbolic substitution and other features. The S/370 mainframe macro assembly language is powerful in its own right with extensive macro features that emulates some higher level language constructs. But at it's essence, assembly languages are still largely cryptic and rigidly formatted.

This project is an attempt to loosen the traditional rigid rules for assembly language that impede easy development and interpretation of source code. There is no logical reason modern assembly needs to be cryptic with a fixed uniform format. There is plenty of processing power on the machines used to build assembler code to provide a richer syntax and something closer to a high level language experience. This is not a new concept, the roots of High Level Assembly (HLA) are from the 1990's.

HLAs in their modern form are exhibited in HLA v2 which has goals very similar to this project. However the abstractions and implementation are much too complex to implement in the FXCore instruction set. HLA is more oriented to general purpose computers than specialty processors like DSPs. For this project it seemed much simpler to expand the macro processor to recognize a more expressive (and yet still simple) syntax to achieve similar goals.