Executing code from lookup RAM
RossH
Posts: 5,660
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.