Shop OBEX P1 Docs P2 Docs Learn Events
Using the shadow registers behind PAR/CNT/INA/INB — Parallax Forums

Using the shadow registers behind PAR/CNT/INA/INB

cgraceycgracey Posts: 14,133
edited 2006-11-05 08:10 in Propeller 1
Here is a trick for squeezing a few longs out of your assembly code:

All special registers within the COG ($1F0-$1FF) are backed by shadow ram registers. In the case of the first four registers which are read-only, these shadow registers can be exploited for DJNZ loops and other purposes which rely on the destination·operand only. For example:

·········MOV···· PAR,#16
:loop··· <some code here>
·········DJNZ··· PAR,#:loop

Note that you could do a 'CMP PAR,#1 WZ' to see, for example, if you were on the last loop. When read as the source operand, PAR will always return the boot parameter, regardless of what is in the shadow register. These same rules apply to CNT, INA, and INB.

It's also very clean to use CNT to track CNT targets in timing loops:

········ MOV···· CNT,#5···· '5 makes the initial WAITCNT·fall through immediately
········ ADD···· CNT,CNT

:loop··· WAITCNT·CNT,#100·· 'here you specify your repetitive timing
········ <some code here>
········ JMP···· #:loop
·
Another nice thing about these shadow registers is that they are all cleared to $00000000 when the cog is booted, giving them a known initial value which can be exploited.

I was scratching my head this afternoon, trying to figure out how I could shave a few longs off a new graphics driver, so that it would fit in the cog. I was already using CTRB (lower bits only, to keep it 'off'), FRQB, and PHSB as general-purpose registers, but needed more. By·getting rid of the general-purpose ram registers being used as counters, and using these 'read-only' registers, instead, I got it packed in!


COG Registers
attachment.php?attachmentid=73564

* Only readable as a Source Register (i.e. MOV DEST,SOURCE)
** Allocated for future use, but not currently implemented

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Chip Gracey
Parallax, Inc.

Post Edited (Chip Gracey (Parallax)) : 11/5/2006 12:13:47 AM GMT

Comments

  • Cliff L. BiffleCliff L. Biffle Posts: 206
    edited 2006-11-05 05:56
    This is sick, in both the traditional "crazy" sense and the newfangled "cool" sense the kids are using. smile.gif

    This explains some of the weird behaviors I've been seeing. propasm only allows these registers to be used in S; this is a direct result of some code I was debugging that used PAR in D and got weird, weird results.

    Now I know why.

    The manual should have enough info about this to give people a clue what might be happening -- but not enough to actually encourage this, because this is pretty far up on the "obscure trick" scale.
  • potatoheadpotatohead Posts: 10,254
    edited 2006-11-05 07:07
    Why not?

    This is a small scale computing platform. Seems to me, these kinds of things are not only encouraged, but mandatory sometimes.

    Over time, we will see more of this and it will make the difference between some projects being average and excellent.

    Part of the fun, frankly!

    ---also kind of educational.

    I see your point and it's all good. I'm not being confrontational, just see it from a different perspective that's all.

    (looking forward to giving your assembler a try soon BTW!)
  • IanMIanM Posts: 40
    edited 2006-11-05 08:10
    I'm working on a pipelined direct digital synthesizer and need a fast way to exit the loop when the main cog wants to change frequency. Is it ok to use the OUTA register for this? eg:

    :loop ...
            ...
            and OUTA,mask wz 'clear the output to allow other cogs access, if mask bit set by control cog, exit
        ifz jmp #:loop
    
    
    :mask long $01000000
    
    



    when the control cog outputs the mask eg or OUTA,mask the other cogs see this and exit.

    Is this ok?

    Cheers, Ian

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ian Mitchell
    www.research.utas.edu.au
Sign In or Register to comment.