p2asm

edit: moved this from another thread

@Dave Hein - While scratching my head I decided to add a bit more info to p2asm such as printing buffer2 on error messages. I found the offending line.
peter:BOOT$ ./p2asm ROM_137PBJ.spin2
ERROR: Expected ",", but found "["
  _HUBBUF       = $0_2000'[128]   ' hub buffer[128] used as default buffer by _HubRxString  (in writable hub ram!!)
By putting a space between the 2000 and the comment it was happy but of course I am now tracking down other funnies.
That was part of Cluso's code btw.

update - I added buffer2 to the "but found" lines even though PrintError should print it but had a segmentation fault. So I fudged the source a few times but eventually realized that Cluso's code doesn't always have whitespace where you would expect. Adding whitespace fixed the errors but I may fork p2asm.c and add some enhancements to it (as time permits).
peter:BOOT$ ./p2asm ROM_137PBJ.spin2
ERROR: Expected "41", but found "  ACMD41= 41 +$40   ' $4000_0000      R1       -       APP_SEND_OP_COND         *Reqs CMD55 first"
Segmentation fault
peter:BOOT$ ./p2asm ROM_137PBJ.spin2
ERROR: Expected "23", but found "  ACMD23= 23 +$40   ' NoBlks[22:0]    R1       -       SET_WR_BLOCK_ERASE_COUNT *Reqs CMD55 first"
Segmentation fault
So the asm source doesn't have whitespace between ACMD41 and the = operator. Also noticed that it doesn't like ackpin without an # operator as it throws an error.
ERROR: Unexpected EOL
ff1c4 156 fc0c0200                         akpin   pinreg                  '..acknowledge pin

After I cleaned up the source these are the remaining errors. BTW, Thanks for your hard work, it is so helpful to obtain a listing!
ERROR: MODZ is undefined
        _RET_   MODZ    _set                      wz    ' "Z" = success
ERROR: MODZ is undefined
        _RET_   MODZ    _set                      wz    ' "Z" = success
ERROR: MODZ is undefined
        _RET_   MODZ      _clr                        wz  '/ return "NZ" = not found
ERROR: MODZ is undefined
        _RET_   MODZ    _set                        wz  ' "Z" = success
ERROR: MODZ is undefined
        _RET_   MODZ    _clr                      wz    ' "NZ" = fail
ERROR: modc is undefined
pRCMOVE                 modc    $0F wc          ' set carry for decrementing (always cleared by PUSH)
ERROR: modc is undefined
        _ret_   modc    0
ERROR: MODZ is undefined
        _RET_   MODZ    _set                      wz    ' "Z" = success
ERROR: MODZ is undefined
        _RET_   MODZ    _set                      wz    ' "Z" = success
ERROR: MODZ is undefined
        _RET_   MODZ      _clr                        wz  '/ return "NZ" = not found
ERROR: MODZ is undefined
        _RET_   MODZ    _set                        wz  ' "Z" = success
ERROR: MODZ is undefined
        _RET_   MODZ    _clr                      wz    ' "NZ" = fail
ERROR: Unexpected EOL
                        akpin   pinreg                  '..acknowledge pin
ERROR: PTR not allowed
        if_z            wrlut   PTRA,retptr             ' save IP onto return stack
ERROR: modc is undefined
pRCMOVE                 modc    $0F wc          ' set carry for decrementing (always cleared by PUSH)
ERROR: modc is undefined
        _ret_   modc    0
ERROR: Unexpected EOL
                        akpin   pinreg                  '..acknowledge pin


I've worked around modc and modz for the moment by using modcz instead. Haven't had a look at PTR not allowed yet.

Tachyon Forth - compact, fast, forthwright and interactive
useforthlogo-s.png
--->CLICK THE LOGO for more links<---
Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
Brisbane, Australia
«1

Comments

  • 34 Comments sorted by Date Added Votes
  • FYI
    MODC and MODZ are aliases in Pnut for MODCZ.
    MODC    c               =       MODCZ   c,0         {WC}
    MODZ    z               =       MODCZ   0,z         {WZ}
    
    Melbourne, Australia
  • Test of pnut modcz aliases
    		modc	0	wc
    		modc	1	wc
    		modc	2	wc
    		modc	3	wc
    		modc	4	wc
    		modc	5	wc
    		modc	6	wc
    		modc	7	wc
    		modc	8	wc
    		modc	9	wc
    		modc	10	wc
    		modc	11	wc
    		modc	12	wc
    		modc	13	wc
    		modc	14	wc
    		modc	15	wc
    		modz	0	wz
    		modz	1	wz
    		modz	2	wz
    		modz	3	wz
    		modz	4	wz
    		modz	5	wz
    		modz	6	wz
    		modz	7	wz
    		modz	8	wz
    		modz	9	wz
    		modz	10	wz
    		modz	11	wz
    		modz	12	wz
    		modz	13	wz
    		modz	14	wz
    		modz	15	wz
    
    Compiles to
    000: FD74006F                  MODCZ   _CLR,_CLR  WC
    001: FD74206F                  MODCZ   _NC_AND_NZ,_CLR  WC
    002: FD74406F                  MODCZ   _NC_AND_Z,_CLR  WC
    003: FD74606F                  MODCZ   _NC,_CLR  WC
    004: FD74806F                  MODCZ   _C_AND_NZ,_CLR  WC
    005: FD74A06F                  MODCZ   _NZ,_CLR  WC
    006: FD74C06F                  MODCZ   _C_NE_Z,_CLR  WC
    007: FD74E06F                  MODCZ   _NC_OR_NZ,_CLR  WC
    008: FD75006F                  MODCZ   _C_AND_Z,_CLR  WC
    009: FD75206F                  MODCZ   _c_EQ_Z,_CLR  WC
    00A: FD75406F                  MODCZ   _z,_CLR  WC
    00B: FD75606F                  MODCZ   _NC_OR_Z,_CLR  WC
    00C: FD75806F                  MODCZ   _c,_CLR  WC
    00D: FD75A06F                  MODCZ   _C_OR_NZ,_CLR  WC
    00E: FD75C06F                  MODCZ   _C_OR_Z,_CLR  WC
    00F: FD75E06F                  MODCZ   _SET,_CLR  WC
    010: FD6C006F                  MODCZ   _CLR,_CLR  WZ
    011: FD6C026F                  MODCZ   _CLR,_NC_AND_NZ  WZ
    012: FD6C046F                  MODCZ   _CLR,_NC_AND_Z  WZ
    013: FD6C066F                  MODCZ   _CLR,_NC  WZ
    014: FD6C086F                  MODCZ   _CLR,_C_AND_NZ  WZ
    015: FD6C0A6F                  MODCZ   _CLR,_NZ  WZ
    016: FD6C0C6F                  MODCZ   _CLR,_C_NE_Z  WZ
    017: FD6C0E6F                  MODCZ   _CLR,_NC_OR_NZ  WZ
    018: FD6C106F                  MODCZ   _CLR,_C_AND_Z  WZ
    019: FD6C126F                  MODCZ   _CLR,_c_EQ_Z  WZ
    01A: FD6C146F                  MODCZ   _CLR,_z  WZ
    01B: FD6C166F                  MODCZ   _CLR,_NC_OR_Z  WZ
    01C: FD6C186F                  MODCZ   _CLR,_c  WZ
    01D: FD6C1A6F                  MODCZ   _CLR,_C_OR_NZ  WZ
    01E: FD6C1C6F                  MODCZ   _CLR,_C_OR_Z  WZ
    01F: FD6C1E6F                  MODCZ   _CLR,_SET  WZ
    
    Melbourne, Australia
  • Thanks for finding the issues with p2asm. Some of those were already on my TODO list, but I haven't gotten around to fixing them yet. I encountered the "ACMD41=" problem when I was trying to assemble another program. I also have the MODZ/MODC aliases on my list of things to do. I think there's a few other aliases I haven't implemented.

    There's also an issue with labels not appearing in the listing if they are on the same line as other code. Looks like it's time to clean up all these issues. Is the file ROM_137PBJ.spin2 available somewhere so I can test with it? If not, I'll just create a file that contains all the issues you pointed out so I can test with it.

  • Peter JakackiPeter Jakacki Posts: 7,704
    edited May 18 Vote Up0Vote Down
    Dave Hein wrote: »
    Thanks for finding the issues with p2asm. Some of those were already on my TODO list, but I haven't gotten around to fixing them yet. I encountered the "ACMD41=" problem when I was trying to assemble another program. I also have the MODZ/MODC aliases on my list of things to do. I think there's a few other aliases I haven't implemented.

    There's also an issue with labels not appearing in the listing if they are on the same line as other code. Looks like it's time to clean up all these issues. Is the file ROM_137PBJ.spin2 available somewhere so I can test with it? If not, I'll just create a file that contains all the issues you pointed out so I can test with it.

    Thanks, you can find that file in my Dropbox P2 folder BOOT folder

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • Ooh. Didn't realise there is a P2ASM.
    Where is it please?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Has anyone done a plugin for NotePad++ ?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Peter JakackiPeter Jakacki Posts: 7,704
    edited May 18 Vote Up0Vote Down
    You can get Dave's p2gcc which includes p2asm from this zip but you need gcc to build it.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • You can get Dave's p2gcc which includes p2asm from this zip but you need gcc to build it.
    :(
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • I checked some fixes to p2asm into GitHub. p2asm can now correctly assemble ROM_137PBJ.spin2, and the binary file matches the binary produced by PNut. The source is included in the attached zip file. I also included a p2asm.exe Windows executable. Cluso, hopefully this will work for you.
  • Peter JakackiPeter Jakacki Posts: 7,704
    edited May 19 Vote Up0Vote Down
    Thanks Dave, you're a champion. I grabbed a zip off github and ran it through the very latest ROM (still testing) without any errors :)

    <link to ROM listing>

    That listing is soooo helpful, I found why my code wasn't running after I combined all the other code it had a byte string at the end which ended up knocking out the word alignment and TAQOZ uses the lsb of a hub code address to indicate jumping rather than calling :)
    fd003              _Enter_TAQOZ
                       ''---------------------------------------------------------------------------------------------------
                       
                       
    fd003     fedfeff9                 loc     PTRA,#_hubrom           ' copy all of ROM to low 64K'
    fd007     fef0eff5                 loc     PTRB,#$C000
    fd00b     ff000008                 rep     #2,##$1000
    fd00f     fcdc0400 
    fd013     fb041761                 rdlong  fx,PTRA++
    fd017     fc6417e1                 wrlong  fx,PTRB++
    

    Add an alignw
    fcfff                              orgh
    fcfff              		alignw
                       		
                       ''-------[ Start TAQOZ ]----------------------------------------------------- <--- start TAQOZr --->
    fd000     fdbffa54 _Start_TAQOZ    call    #@_reset_booter                 ' reset the booters interrupts and autobaud
                       
    fd004              _Enter_TAQOZ
                       ''---------------------------------------------------------------------------------------------------
                       
                       
    fd004     fedfeff8                 loc     PTRA,#_hubrom           ' copy all of ROM to low 64K'
    fd008     fef0eff4                 loc     PTRB,#$C000
    fd00c     ff000008                 rep     #2,##$1000
    


    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    P2 SHORTFORM DATASHEET +++++ TAQOZ documentation
    Brisbane, Australia
  • Thanks Dave. Peter sent me a copy of the output looks great!
    I have downloaded now. Thanks for the exe ;)
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • FWIW
    Anyone with W10 will need to open a command line and supply the filename as a parameter. It helps to have P2ASM and the source file in the same folder.

    Dave,
    Thanks for this. Already proved useful with a bug to call the ROM routines. Was using a string in cog but it needs to be in hub and I forgot. The listing showed it up straight away :)

    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • @Dave Hein I too am liking your p2asm listing!
    But it looks like p2asm is having a problem in the CON section digesting the bitwise decode "|<" (and maybe encode?) ">|" operators:
    ' USB receiver RDPIN status bit positions:
            #0, J_IDLEB, K_RESUMEB, SE0_RESETB, SE1_BADB, SOPB, EOPB, RXERRB, BYTE_TGLB
    ' USB receiver RDPIN status bitflags:
            J_IDLEF    = |< J_IDLEB
            K_RESUMEF  = |< K_RESUMEB
            SE0_RESETF = |< SE0_RESETB
            SE1_BADF   = |< SE1_BADB
            SOPF       = |< SOPB
            EOPF       = |< EOPB
            RXERRF     = |< RXERRB
            BYTE_TGLF  = |< BYTE_TGLB
    
    and the enumeration[offset] syntax option:
    '------------------------------------------------------------------------------
    ' HID Class Requests (v1.11 HID Device Class Definition, Section 7.2):
    '------------------------------------------------------------------------------
            #$01, HID_GET_REPORT, HID_GET_IDLE, HID_GET_PROTO[6] ' $04 - $08 reserved
            HID_SET_REPORT, HID_SET_IDLE, HID_SET_PROTO
    ' HID Descriptor types:
            #$21, TYPE_HID, TYPE_REPORT, TYPE_PHYSICAL ' HID types $24 - $2f are reserved
    

    I've attached the full source in case you'd like to use it as a test case.
    garryj
  • I'll look into it. I'm pretty sure I hadn't implemented those features. It shouldn't be too hard to add them.
  • Dave HeinDave Hein Posts: 5,574
    edited May 27 Vote Up0Vote Down
    @garryj, I fixed the problems that p2asm was having with USBHost and I checked it into GitHub. I added support for the |< operator, and also support for handling HID_GET_PROTO[6]. I wasn't aware that [n] could be used in a CON section to increment the enum value.

    I also found that I wasn't handling forward references to constants correctly. I had to restructure how I parse the source file to fix it. Previously, I used 2 passes, where the first pass gathered symbols and their values, and the second pass generated code. However, Spin/PASM requires processing all the CON symbols first, and then the next 2 passes are performed. If constants reference other constants that are defined later in the file it actually requires an additional pass through the source file.


    Thanks for posting the USBHost code. I added it to the list of programs that I use to test the assembler.
  • Just ran a test build and it works great! Thanks, Dave, for taking the time to do this!
    garryj
  • @Dave Hein, I've come across a couple more p2asm compile issues:
    If a constant larger than 9 bits is used with "#" instead of "##", the compiler does not issue an "out of range" error, e.g. mov reg, #54321 with p2asm will compile without error, but pnut throws a "Constant must be from 0 to 511" error.

    It appears p2asm does not yet support PTRx expressions with AUGS to get 20 bit unscaled indexing, e.g. wrbyte reg, ptra[##54321] throws:
    ERROR: Expected "]", but found "54321"
                    wrword  reg, ptra[##54321]
    P2 doc:
    If AUGS is used to augment the #S value to 32 bits, the #S value will be interpreted differently:
    
        #%0AAAAAAAA					- No AUGS, 8-bit immediate address
        #%1SUPNNNNN					- No AUGS, PTRx expression with 5-bit scaled index
        ##%000000000000AAAAAAAAAAA_AAAAAAAAA	- AUGS, 20-bit immediate address
        ##%000000001SUPNNNNNNNNNNN_NNNNNNNNN	- AUGS, PTRx expression with 20-bit unscaled index
    PTRx expressions with AUGS:
    
    If "##" is used before the index value in a PTRx expression, the assembler will automatically insert an AUGS instruction and assemble the 20-bit index instruction pair:
    
        RDBYTE  D,++PTRB[##$12345]
    ...becomes...
        1111 1111000 000 000111000 010010001     AUGS    #$00E12345
        1111 1010110 001 DDDDDDDDD 101000101     RDBYTE  D,#$00E12345 & $1FF
    
    Neither is a show stopper, though the # vs. ## did catch me out a couple of times. I very much appreciate what you've done with p2asm!
    garryj
  • I did add error checks for immediate source values a few weeks ago. I checked it into GitHub, but I haven't posted it to the p2gcc thread. p2asm still doesn't support using ## with pointers. I'll add support for that the next time I work on it.
  • jmgjmg Posts: 12,042
    garryj wrote: »
    @Dave Hein, I've come across a couple more p2asm compile issues:
    If a constant larger than 9 bits is used with "#" instead of "##", the compiler does not issue an "out of range" error, e.g. mov reg, #54321 with p2asm will compile without error, but pnut throws a "Constant must be from 0 to 511" error.
    ..
    Neither is a show stopper, though the # vs. ## did catch me out a couple of times. I very much appreciate what you've done with p2asm!
    Does it truncate, or assemble correctly ?
    There is a case to have the assembler manage this automatically, where it can do so in an unambiguous manner. Just like most Assemblers now manage CALLs.
    ie If it knows CONST is > 511, simply promote to the larger form, possibly with a comment in the listing.
    ##<511 still allows force of larger form, should users want that for some reason.
  • This code that is in GitHub will print out an error statement, and it assembles the lower 9 bits of the constant into the instruction. However, I can see the argument for automatically generating an AUGS/AUGD, and handling it as a 32-bit immediate.
  • Thanks, Dave!

    I picked up the GitHub code and the way you have the # vs. ## immediate error reporting works for me. If p2asm promotes an immediate > 511 to use augs/augd in the future, that would be OK too, as long as a warning gets raised so I can keep pnut happy, too :smile:
    garryj
  • I've managed to bump into p2asm's current symbol limit of 2,000. PNut_v32j included a symbol limit expansion, but I haven't been able to find the exact number for its new max, so I've just upped my local symsubs.h MAX_SYMBOLS to 5,000 for now and all is good :smiley:

    Also, I've run across a minor issue regarding ".local" symbols being accessible when they should be out of scope:
    dat
                    org
    
    start
                    mov     x, #0
                    mov     y, 20
                    jmp     #.exit
    loop
                    add     x, #1
                    djnz    y, #loop
    .exit
                    jmp     #$
    
    x               res 1
    y               res 1
    
    p2asm will assemble with no error, but PNut catches it and throws an "Undefined symbol" error.
    garryj
  • I think I've run into the symbol limit before also. I thought I had increased it, but I checked, and it was still at 2000. I just checked a changed into the repository to increase it to 5000.

    p2asm handles local labels a bit differently than PNut. Local labels are valid until the global label following the local label. Any code written for PNut will work with p2asm, but not vice-versa. I found it easier to implement it that way. If it becomes a problem I will change the handling of local labels to match PNut, but for now I'll probably leave it as is.

    BTW, local labels are disabled when the assembler generates an object file. This is because local labels conflict with the code generated by GCC that generates labels like .Lxxxx. I'm not sure why we changed from :label to .label, but I did mention the conflict with GCC at the time.
  • Thanks for the explanation regarding local labels. Now that I'm aware it's a non-issue. Thanks!
    garryj
  • Yes, we ran into the limit in pnut when compiling the rom. TAQOZ uses lots of labels. So Chip increased the limit for pnut v32j.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Why aren't you dynamically allocating the symbol table? Why bother users with having to recompile it when their projects have more than the default limit?
  • evanhevanh Posts: 5,383
    edited October 15 Vote Up0Vote Down
    It's the natural of using tables rather than a dynamic vs static allocation issue. They're quick to operate but, once allocated, are fixed in size without some shenanigans.
    "Are we alone in the universe?"
    "Yes," said the Oracle.
    "So there's no other life out there?"
    "There is. They're alone too."
  • When I first wrote p2asm I decided to use a simple array rather than a dynamically allocated linked list. It would be fairly easy to change to a linked list since the relevant code is mostly contained within symsubs.c. I'll keep it in mind.
  • Hello!

    I saw Peter Jakacki's mention of Tachyon Forth on comp.lang.forth --- sounded like a good Forth system --- also, the P2 seems to be an intriguing processor.

    It is intriguing because it is possible to ban the use of interrupts. You have multiple cogs, so you don't really need interrupts.
    This means that RTC (Return-stack Threaded Code) can be used. This is generally the 2nd fastest threading scheme --- STC (Subroutine Threaded Code) is generally the 1st fastest.
    In RTC you use the return-stack pointer as your Forth IP register --- it points to the threaded code --- so, NEXT is a RET instruction.
    You would use another register for your return-stack pointer.
    The advantage of RTC over STC is that you can write your primitives using a traditional assembler, typically provided by the chip manufacturer --- with STC you have to meta-compile machine-code at run-time, typically with your own assembler --- also, another advantage of RTC over STC is that the code is usually less bloaty.

    I might be interested in writing a Forth system for the P2 using RTC. This wouldn't compete directly against Tachyon Forth, because they have different goals. He is using byte-code for the purpose of reducing code size. I would be using RTC for the purpose of increasing execution speed, at the cost of more bloaty code.

    I would need some info on the P2. The only thing I've found so far is: https://www.dropbox.com/s/l5w3voyknyae2k2/P2 instruction set.xlsx?dl=0
    This is pretty good info, but not everything I need. In the opcodes, you have 9 bits specifying a register, so I assume there are 512 registers. Is this true?
    This is a 32-bit processor, so I assume the registers are 32-bit. The address space is 1 megabyte though, right?
    When CALL is done, is a 32-bit address pushed onto the return-stack? So RET expects a 32-bit number, although it only uses the lower 20 bits for the address. Is this true?

    How many clock cycles does RET take? Peter Jakacki says he can do NEXT for byte-code in 6 clock cycles --- if RET takes 6 then RTC is not worthwhile --- it would have to take 3 to double the speed over byte-code, which would make it worthwhile.

    I would need a lot more info on the P2 to get started --- any pointers would be appreciated --- thanks in advance.

  • In the opcodes, you have 9 bits specifying a register, so I assume there are 512 registers. Is this true?
    yes.
    This is a 32-bit processor, so I assume the registers are 32-bit. The address space is 1 megabyte though, right?
    yes and no.
    P2 silicon is limited to 512k HUB, but the FPGA versions have 1MB when the FPGA can do that.
    When CALL is done, is a 32-bit address pushed onto the return-stack? So RET expects a 32-bit number, although it only uses the lower 20 bits for the address. Is this true?
    IIRC the stack is only as wide as it needs to be, and I think the non-address bits are ignored

    I would need a lot more info on the P2 to get started --- any pointers would be appreciated --- thanks in advance.
    On page 1, 1st post here are Document links - these show the Cycles/opcode timing, which can depend on where code runs from.
    COG execution is always fastest.


    https://forums.parallax.com/discussion/162298/prop2-fpga-files-updated-2-june-2018-final-version-32i/p1

Sign In or Register to comment.