Executing code from lookup RAM
RossH
Posts: 5,462
in Propeller 2
I was under the impression that on the Prop2 we could execute code from lookup RAM just like hub RAM, by putting the code at $200. But I can't seem to get it working. Can anyone tell me what's wrong with the following code? It works correctly if start_cog is at $100, but not if I force it to be at $200.
What am I doing wrong?
What am I doing wrong?
DAT org 0 start cogid hex_value call #\Flash_Hex call #\start_cog loop jmp #loop led_mask long |< (56-32) hex_value long $10203040 hex_count long $0 flash_count long $0 ' orgf $200 ' put start_cog in lookup RAM orgf $100 ' put start_cog in hub RAM start_cog coginit #%1_0000, #start wc ret '--DEBUGGING FUNCTIONS ----------------------------------------- CON blip_time = 1_000_000 hex_time = 10_000_000 flash_time = 5_000_000 DAT orgh $1000 ' ' LED_On - turn LED on ' LED_On or dirb,led_mask andn outb,led_mask ret ' ' LED_Off - turn LED off ' LED_Off or dirb,led_mask or outb,led_mask ret ' ' Flash_LED - flash the LED flash_count times ' Flash_LED cmp flash_count,#0 wz if_z waitx ##flash_time if_z jmp #done_flash flash_loop call #LED_On waitx ##flash_time call #LED_Off waitx ##flash_time djnz flash_count,#flash_loop done_flash ret ' ' Blip_LED - flash LED briefly (e.g. used to indicate zero) ' Blip_LED call #LED_On waitx ##blip_time call #LED_Off waitx ##flash_time ret ' ' Flash_Hex - flash the LED to display up to 8 hex digits in hex_value ' Flash_Hex cogid hex_count mov led_mask,##|<(56-32) shl led_mask,hex_count mov hex_count,#8 digit_loop1 ' skip leading zeroes rol hex_value,#4 mov flash_count,hex_value and flash_count,#$f wz if_z djnz hex_count,#digit_loop1 ' if all we have are zeroes, do one blip tjnz hex_count,#digit_loop2 call #Blip_LED jmp #done digit_loop2 tjnz flash_count,#do_flash ' for zero digits, do one blip call #Blip_LED jmp #do_next do_flash ' for non-zero digits, flash the digit count call #Flash_LED do_next djz hex_count,#done waitx ##hex_time rol hex_value,#4 mov flash_count,hex_value and flash_count,#$f jmp #digit_loop2 done waitx ##hex_time*2 ret
Comments
Oh, you have to copy it into LUT first?
https://forums.parallax.com/discussion/165903/how-to-write-lut-exec-assembly-code
Aha! Thanks.
Yes, still getting used to that one
Need to copy code into lut first ...
Here's my subroutine wrapper code:
Yes, I am intending to do the same thing. Thanks for the wrapper code.
And the _RET_ cannot restore the C & Z flags, but you can with RET wc/wz/wcz
As others have already mentioned, you have to explicitly load the LUT RAM with code before trying to execute from it. A few other points:
- Unlike P1+LMM, P2+hubexec runs at full speed except for branches, which incur a hub lookup penalty
- As I result I was surprised at how little difference putting code in LUT makes. It's worth it for small loops (particularly if you can use REP) but in general hubexec works pretty well
- The other reason to keep code in LUT is if you need to use the rdfast/wrfast mechanism, which conflicts with hubexec
- Oddly enough, it's more efficient to keep code in LUT and tables in COG RAM than the reverse. "rdlut" takes 3 cycles to execute, as opposed to 2 cycles for accessing COG memory, so getting data from COG memory is 50% faster than getting it from LUT memory
Regards,
Eric
It's rare for the COG code to actually fill $200 longs (especially since the last $10 are registers). Besides, instead of: it's actually 1 instruction shorter to do:
I'd still prefer to see different mnemonics for these instructions (loc and locrel, or locabs and locrel, or whatever) instead of the backslash, but that's another story.