(as of the 2015-10-13 PNUT release)
So. Because the addressing and labeling syntax has been a bit of a moving target, I wanted to try to document this thoroughly. Yes, some of this is obvious, but I wanted a "big picture" coverage of the topic. So here it is...
- Labels are either globally-scoped or locally-scoped.
- A globally-scoped label must begin with an underscore or letter (a-z, A-Z). All other characters must be an underscore, letter (a-z, A-Z) or number (0-9).
- A locally-scoped label must begin with a period, followed by an underscore or letter (a-z, A-Z). All other characters must be an underscore, letter (a-z, A-Z) or number (0-9).
- Each local scope begins immediately after each global label and ends immediately before the next global label.
- All labels must be unique within the scope they belong to.
- Labels defined in an ORGH section resolve to a hub address or offset (in bytes), regardless of whether the label is referenced in an ORGH or ORG section.
- Labels defined in an ORG section resolve to a cog address or offset (in longs), regardless of whether the label is referenced in an ORGH or ORG section.
- When the effective hub address or offset is needed for a label that is defined in an ORG section, the label may be preceded by a "@" to force resolution to a hub address or offset.
- Though it is possible to apply the "@" to labels defined in ORGH sections, it has no effect.
- Expressions can contain numbers, labels, and nested expressions. The simplest expression is either a single number or label.
- An expression that begins with # or ## is known as an "immediate" value.
- For branching instructions, immediate values can be either "absolute" or "relative", depending on context.
- For non-branching instructions, immediate values are always "absolute".
- "Absolute immediate" interpretation can be forced by using "#\" or "##\".
- There is no operator for forcing a "relative immediate" interpretation.
- # means 9-bit (short-form) or 20-bit (long-form) immediate value:
- For short-form branch instructions, this is a 9-bit relative immediate.
- For long-form branch instructions that change execution mode (cog <-> hub), this is a 20-bit absolute immediate.
- For long-form branch instructions that do not change execution mode, this is a 20-bit relative immediate.
- For all other instructions, this is a 9-bit absolute immediate.
- In circumstances where an absolute immediate must be forced, the expression is prefaced with "#\".
- ## means 32-bit immediate value
- An implicit AUGx will precede the instruction containing the expression.
- The lower 9 bits will be encoded in the instruction and the upper 23 bits will be encoded in the AUGx.
- For short-form branch instructions, this is a 20-bit relative immediate. The upper 12 bits are ignored.
- For non-branch instructions, this is a 32-bit absolute immediate.
- This is meaningless for long-form branche instructions. PNUT throws an error.
- For BYTE/WORD/LONG, the expression is encoded as raw data. If the expression begins with # or ##, PNUT throws an error.
- For all other expressions that do not begin with # or ##, the expression is encoded as a register address and must be between $000 and $1FF.
Does this look right to everyone else? Anything to add, change, or remove?
(edit: clarified expression branching vs. non-branching immediate values, as suggested by @Electrodude
(edit: clarified label naming and fixed typo, as pointed out by @mindrobots
(edit: Updated "@" usage to better align with comments by @cgracey