p2asm

in Propeller 2
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.
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).
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!
I've worked around modc and modz for the moment by using modcz instead. Haven't had a look at PTR not allowed yet.
@"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.
Comments
MODC and MODZ are aliases in Pnut for MODCZ.
MODC c = MODCZ c,0 {WC} MODZ z = MODCZ 0,z {WZ}
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 to000: 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
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
Where is it please?
<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
I have downloaded now. Thanks for the exe
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
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.
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.
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!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.
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
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.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.
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.
yes and no.
P2 silicon is limited to 512k HUB, but the FPGA versions have 1MB when the FPGA can do that.
IIRC the stack is only as wide as it needs to be, and I think the non-address bits are ignored
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