Is there a better description of the p2 instructions than the Rev B doc and spreadsheet?

I am looking for a better description of the PASM instructions for the P2 than what is in the documentation for the Rev B silicon and the instruction spreadsheet. I'm having a hard time understanding the documentation. Abbreviations are used without explanation. There is a lot of assumed knowledge that I don't have. In the old P1 book, there was a fair explanation for each instruction that included some examples of usage. More than the ddddddddd sssssssss type of discussion. I am assuming because the P2 is so new that this type of documentation hasn't been developed yet, although if I wait it will become available. I'm just too impatient. I am just wondering if there is something I'm not aware of.

Steve

Comments

  • AFAIK there's not. The docs are in flux/progress as Chip finishes SPIN2.

    You'll likely find a lot of answers in Propeller 2 forum threads, although sure - that can be a lot of digging sometimes!

    Best advice for now, is to ask anything you need in the Propeller 2 thread, or use the Search box. There's lot's of experts here that have the knowledge you seek!
  • RaymanRayman Posts: 10,207
    edited 2020-01-14 - 21:04:35
    There is a text file that comes with PNut…
    It has some details that I don't think are anywhere else...

    Actually, I guess that isn't much help...
  • RaymanRayman Posts: 10,207
    edited 2020-01-14 - 21:09:35
    We do need a "Propeller II Manual", like we do for P1.

    I guess the good news is that P2 ASM is largely a superset of P1 ASM.
    So, the reads and moves and shifts work more or less the same way.

    One thing about the spreadsheet is that it often has exact FPGA code for the result. So, if you can read Verilog (I think it was), then you're in good shape.

    The documentation file is a pretty good resource though.
    What abbreviations need explaining?
    I think anybody can make notes in the documentation if more explanation is needed...
  • There was a document on google? that detailed many of the instructions. However, as P2 changed this became out of date with the bit definitions although mostly the instructions still worked the same way. Not sure where that document is these days. Perhaps Peter J can chime in as IIRC he did a lot of that work.

    Note that many of the P2 base instructions are the same as the P1 base instructions, with just the bit positions being different, and of course there is no 'NR' bit, and the no-op condition '0000' is now an implied _RET_.
    Most condition flags are the same, but not all.
  • As Cluso says, the simpler instructions are just like the prop1, with the exact behaviour concisely in the google spreadsheet. There won't be full prop1 type documentation for a while. I won't try to guess how long.

    The more complex instructions are explicitly documented in the big google doc. Things like how to use all the ALTx instructions, uses of SETQ and it's Q register, HUBSET, COGINIT, SKIP, REP, RDFAST, ... SETCMOD colour space config. How to config events and interrupts. Even the Cordic instructions have their section. Streamers and smartpins too of course.
  • The instructions.txt file contains the assembler directives like ORG, DAT, FIT. Things like # and @ were first described there too.
  • I was trying to learn how to use the cog ram to implement a simple stack. So I wanted to simply create a base address and a stack pointer. Store some data on the stack. Read it back and compare what I stored with another temp register. Here is what I have done so far.
    ' Stack test 
    ' assembly language stack test program
    
    con
    
      freq = 160_000_000
      mode = $010007f8
      delay = freq / 10
    
    dat
        org
    
        ' set up clock
        hubset #0
        hubset ##mode  ' initialize oscillator
        waitx ##20_000_000/100 ' wait for it to settle down
        hubset ##mode + %11   ' enable it
    
    
    		mov sb, #$100	' Set stack base to $100
    		mov sp, #1	' Set some data in sp
    		alts sb		' Try to set up sb as a pointer of where to write data
    		mov sb, sp 	' Write data ( a 1) onto the stack
    		alts sb
                    mov x, sb
    		mov y, #1
    		sub x, y wz	' Subrtract the two temp registers
    	if_z	jmp #test1
    		jmp #test2
    
    test1		mov x, #56	' Set x to blink 1st pin  values are equal
    		drvnot x	' Toggle pin 56
    		shl x, #18
    		waitx x
    		jmp #test1
    test2		mov x, #63	' Set pin 63  Values are not equal
    		drvnot x
    		shl x, #18	
    		waitx x
    		jmp #test2
    		
     	
    
    
    sb	res 1		' stack base
    sp	res 1		' stack pointer
    x	res 1		' temporary register
    y	res 1		' Temporary register
    
  • Shouldn't that first "alts sb" be "altd sb"?

    Also, a lot of people would write "mov 0-0,sp" on the next line where "0-0" just means that it is a value that will be overwritten...
  • Thank you. That is what I was missing. My little example is now working with those two changes.

    Steve
  • @Steve_Hatch,
    Is this just a test or are you trying to do something because there is a small 8 deep stack internally in each COG that supports calls/returns as well as push/pop. There are also registers PTRA/PTRB/PA/PB that can be used as pointers to registers with auto increment/decrement that can be useful for creating stacks especially in HUB and possibly in COG or LUT too.
  • PTRA/B can only be a direct address when used with RDLONG/RDLUT type instructions. They can't address cogRAM without use of ALTx prefixes, same as any general register.

    I'd guess Steve is just using a stacking mechanism to test out the ALTx instructions.

  • AJLAJL Posts: 259
    edited 2020-01-15 - 01:35:36
    I was trying to learn how to use the cog ram to implement a simple stack. So I wanted to simply create a base address and a stack pointer. Store some data on the stack. Read it back and compare what I stored with another temp register. Here is what I have done so far.
    @Steve_Hatch,

    I've reproduced your code with comments updated to cover what actually happens and some efficiencies added
    ' Stack test 
    ' assembly language stack test program
    
    con
    
      freq = 160_000_000
      mode = $010007f8
      delay = freq / 10
    
    
    dat
        org
    
        ' set up clock
        hubset #0
        hubset ##mode  ' initialize oscillator
        waitx ##20_000_000/100 ' wait for it to settle down
        hubset ##mode + %11   ' enable it
    
    
    		mov sb, #$100	' Set stack base to $100
    		mov sp, #1	' Set some data in sp; stack pointer is normally added to the stack base to get the current stack entry
    '		alts sb		' Replace s field of next instruction with address of sb register; removal of this instruction would make no difference
    		mov sb, sp 	' Effectively No-op: Write contents of sb to sb
    '		alts sb             ' Removal of this instruction would make no difference
    '                mov x, sb        ' Could be eliminated if a CMP instruction was used in place of the SUB below
    '		mov y, #1
    '		sub x, y wz	' Subtract the two temp registers
                    cmp sb, #1 wz ' Single instruction to replace three
    	if_z	jmp #test1
    		jmp #test2
    
    test1		'mov x, #56	' Set x to blink 1st pin  values are equal; use of immediate in drvnot eliminates the need to use a variable
    		drvnot #56	' Toggle pin 56
    		'shl x, #18
    		waitx ##56<<18
    		jmp #test1
    test2		'mov x, #63	' Set pin 63  Values are not equal; use of pin 63 is potentially problematic as this is a serial boot pin
    		drvnot #63
    '		shl x, #18	
    		waitx ##63<<18
    		jmp #test2
    		
     	
    
    
    sb	res 1		' stack base
    sp	res 1		' stack pointer
    x	res 1		' temporary register
    y	res 1		' Temporary register
    

    Here's code that is closer to what I think you want, if you specifically want to use cog ram (a limited resource) for your stack:
    ' Stack test 
    ' assembly language stack test program
    
    con
    
      freq = 160_000_000
      mode = $010007f8     ' gives 160MHz from 20MHz crystal
      delay = freq / 10
      sb = $100
    
    dat
        org
    
        ' set up clock
        hubset #0
        hubset ##mode  ' initialize oscillator
        waitx ##20_000_000/100 ' wait for it to settle down
        hubset ##mode + %11   ' enable it
    
    
    
    		mov sp, #0	' Set stack pointer to zero, so that written address is $100
                    mov data, #5   ' Initialise data
    
    		 altd sp, #sb	' set stack address as destination of next instruction to push to stack 
    		 mov 0-0, data 	' push data to stack
    		 add sp, #1        ' Update stack pointer; normally would have some code here to deal with stack over-flow
    
      ' now pop value from top of stack
                    sub sp, #1 wz   ' Point to value to be popped
      ' there should be some code here testing Z to deal with stack under-flow
    		alts sp, #sb      ' set stack address as destination of source of next instruction to pop from stack
                    mov odata, 0-0
                    cmp odata, data wz ' popped data matches pushed data?
    	if_nz	jmp #failure
    
                    rep #2,#0
            	 drvnot #56	' values match; toggle pin 56
    		 waitx ##delay ' toggle at 5 Hz
    
    failure	rep #2, #0
                     drvnot #57       'something went wrong; toggle pin 57
    		 waitx ##delay ' toggle at 5 Hz
    
    		
     	
    
    
    sb	res 1		' stack base
    sp	res 1		' stack pointer
    data	res 1		' push data register
    odata	res 1		' pop data register
    

    lut ram is also worth considering for stacks as you have the rdlut and wrlut instructions that can update the pointer automatically as part of the operation. and as @Cluso99 has mentioned, there's a hardware stack in each cog, and hubram is a viable option for stacks too.
  • There was this document I was doing up years ago and I guess I could bring it up to date, perhaps with some collaborative effort?
    Here is the link to the static pubdoc version too.
Sign In or Register to comment.