Shop OBEX P1 Docs P2 Docs Learn Events
P2asm assembler features? — Parallax Forums

P2asm assembler features?

Your favorite? P2 noob is back with more inane questions! :smiley:

I've been trying to find some information on what assembler features are supported in the assemblers that are out there. I've skimmed the following documents to try and find out:

  • Spin2 doc v52
  • Silicon doc v35
  • PASM2 manual from 2022

I have not been able to find out things like:

  • Do we have local labels?
  • Do we have macros?

And probably more stuff that I've missed.

If there's some documentation I've missed then it'd be super helpful if someone could point me at it. I'm currently using flexspin as my assembler, but from what I've gathered the assemblers available for the P2 all seem to have the same feature set pretty much, and are largely compatible with each other.

Thanks a lot!

Comments

  • evanhevanh Posts: 16,905
    edited 2025-11-10 12:37

    Labels is it. There is two levels, labels with a leading dot have locality between undotted labels.

    Or at least that's true for all the Pasm2 assemblers that I've used. Pasm1 used a leading colon instead.

  • evanhevanh Posts: 16,905

    TMM,
    I haven't looked at it myself but maybe working from a RISC-V emulator would be of interest for your project? Eric is pretty good at undertaking useful feature requests too - https://forums.parallax.com/discussion/170295/riscvp2-a-c-and-c-compiler-for-p2/p1

  • The first observation to make here is that the mainstream P2 assemblers (PNut, Spin Tools and flexspin) are really Spin2 compilers. Spin2 supports both inline ASM and DAT block ASM directly in its syntax (unlike C et al where it's very poorly integrated). "pure ASM" mode where no Spin runtime or compiled HLL code is emitted into the binary is essentially a special-case subset of the regular Spin2 syntax where only CON and DAT blocks are used.

    Thus they all have the same basic syntax and features:

    • local labels start with a leading dot
    • CON block constants and any constant expression can be used as values
    • FILE directive
    • convenient syntax for AUGS/AUGD
    • predefined symbols for pin modes etc.
    • (semi-new) DITTO unrolling
    • etc etc

    Flexspin's extensions:

    • C-style preprocessor (#include, #ifdef and such) - doesn't really support full C macro expansion
    • triple @@@ true address operator (not relevant to pure mode)
    • conditional assembly (if/else/end based on constant expression)
    • accessing local labels from outside their scope (this inexplicably uses a colon even in P2ASM, like foo:bar to access .bar defined under global label foo)
    • (semi-new) label namespaces (essentially another layer of scoping)

    see also: https://github.com/totalspectrum/spin2cpp/blob/master/doc/spin.md

    Spin Tools also has some equivalent to most of these extensions, but they're not quite compatible.

    One thing to note here is that the Spin2 syntax descends from Spin1 and the P1. On the P1, PASM is used in a more microcode-like fashion. The P1 does not have hubexec, the 496 longs of code loaded into cog RAM is all there is, and you'd use that to build some sort of virtual system component. On P1, the Spin bytecode interpreter is ROM-resident and essentially is the actual CPU you program for and user PASM is essentially used to implement high-speed virtual peripherals. This paradigm of course never leads to very large PASM programs in a single file, so the language never grew facilities to handle such. (of course we are all very clever folks and figured ways to subvert this system, though in the end the Spin interpreter always wins on code density, which is possibly the most important thing on a 32K RAM machine).

    The P2 deliberately is designed such that its PASM can be treated as a more normalTM CPU instruction set (execute from main memory, relative branches, stack-based CALL/RET, etc), but the tooling all descends from the P1 tooling and is therefore ill-equipped for larger programs. e.g. without the namespace extension or careful use of naming conventions, you can very easily reference a cog/lut label that doesn't exist in the cog running the code and cause horrible bugs. (I essentially suggested the namespace extension after writing a lot of code with just prefix naming to stop this problem. See for example my SNES emulator - this one has the misfortune of having ppr_, ppc_ and ppm_ prefixes to keep 3 cogs processing graphics from having label name collisions - this doesn't really help code readability)

Sign In or Register to comment.