Shop OBEX P1 Docs P2 Docs Learn Events
Fun with Cog Special Purpose Registers — Parallax Forums

Fun with Cog Special Purpose Registers

hippyhippy Posts: 1,981
edited 2008-03-11 13:56 in Propeller 1
There's a comment in the thread on "what do people want for the Prop II" from Chip about executing code held in a Cog's Special Purpose Registers ($1F0-$1FF) which I hadn't paid much attention to or appreciated before, but is quite interesting. Maybe it's not news to everyone but some people may find it useful or at least interesting as well. If not, just ignore this post smile.gif

Providing nothing is written to the SPR which affects the physical configuration of the Cog ( for example writing DIRA with non-zero will create an output pin ), code can be written and then executed. What's executed is whatever was written, not what would be read if that SPR were used as a source register in an instruction. That makes $1F0 to $1F5 available for use.

Code has to be moved into the SPR because it cannot be loaded as a part of CogNew which is a shame, but it may have some use somewhere. The following runs in SPR and increments a long in Hub memory ...

CON         
  _CLKMODE            = XTAL1 + PLL16x
  _XINFREQ            = 5_000_000
  TV_PIN              = 12

OBJ
  tv                  : "TV_Text"

VAR
  long counter
  
PUB Main
  tv.Start( TV_PIN )
  CogNew( @IncHub, @counter )
  repeat
    tv.Out( 1 )
    tv.Dec( counter )

DAT

IncHub        org       $000

              mov       $1F0,x1F0
              mov       $1F1,x1F1
              mov       $1F2,x1F2
              mov       $1F3,x1F3
              mov       $1F4,x1F4
              mov       $1F5,x1F5
              
              jmp       #$1F0                 

tmp           long      0

x1F0          rdlong    tmp,PAR      ' $1F0 - PAR
x1F1          add       tmp,#1       ' $1F1 - CNT
x1F2          wrlong    tmp,PAR      ' $1F2 - INA
x1F3          nop                    ' $1F3 - INB
x1F4          nop                    ' $1F4 - OUTA
x1F5          jmp       #$1F0        ' $1F5 - OUTB





Note how the rdlong at $1F0 is executed as a rdlong not the instruction the value passed in as PAR represents, yet when PAR is used in that rdlong the actual PAR register is used to get the address which should be read.

Post Edited (hippy) : 3/11/2008 5:20:30 AM GMT

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2008-03-11 08:10
    It will generally be safer to use the SPR as variables only, when short of memory smile.gif
    Very popular are things as:
    MOV INA, NN
    ....
    DJNZ INA,...

    Note that this double use affects the 6 "Read Only Registsters" (which obviously is a mis-nomer) only: PAR, CNT, INA, INB, PHSA, PHSB.
  • hippyhippy Posts: 1,981
    edited 2008-03-11 13:56
    @ deSilva : OUTA, OUTB are also available providing the Cog does not need to control any output pins.

    Here's a 'zero-footprint' LMM implementation which runs entirely in SPR ( the loading code can be zeroed as part of Cog initialisation ). Once LMM is running the LMM code has unrestricted use of all 496 registers, SPR and I/O ( except on Prop II because OUTB is used ).

    Being kernel-less means jumps, calls and loads of values over $1FF have to be handled somewhat convolutedly in the LMM itself so it's not necessarily practical but could have possibilities.

    This uses LMM to increment the long at $7FFC ...

    CON         
      _CLKMODE            = XTAL1 + PLL16x
      _XINFREQ            = 5_000_000
      TV_PIN              = 12
    
    OBJ
      tv                  : "TV_Text"
    
    PUB Main
      tv.Start( TV_PIN )
      CogNew( @RunLmm, @Lmm )
      repeat
        tv.Out( 1 )
        tv.Dec( long[noparse][[/noparse] $7FFC ] )
    
    DAT
    
    Lmm           mov       $000,PAR
                  add       $000,#Lmm_Loop-Lmm
    
                  mov       $001,#$7F
                  shl       $001,#8
                  or        $001,#$FC
    
    Lmm_Loop      rdlong    $002,$001
                  add       $002,#1
                  wrlong    $002,$001
                  mov       $1F5,$000
                  
    DAT
    
    RunLmm        org       $000
    
                  mov       $1F0,x1F0
                  mov       $1F1,x1F1
                  mov       $1F2,x1F2
                  mov       $1F3,x1F3
    
                  mov       $1F5,PAR
                  
                  jmp       #$1F0                 
    
    x1F0          rdlong    $1F2,$1F5    ' $1F0 - PAR - Fetch
    x1F1          add       $1F5,#4      ' $1F1 - CNT - Increment LMM PC
    x1F2          nop                    ' $1F2 - INA - Execute LMM opcode
    x1F3          jmp       #$1F0        ' $1F3 - INB - Repeat
    x1F4          res       1            ' $1F4 - OUTA - Used for I/O control
    x1F5          res       1            ' $1F5 - OUTB - LMM PC
    
    
    
Sign In or Register to comment.