P2 Tricks, Traps & Differences between P1 (Reference Material Only)

2»

Comments

  • ozpropdev wrote: »
    P2 does have a NOP opcode.
    0000 0000000 000 000000000 000000000        NOP
    

    Yes, all zeros is a special "NOP" case and is trapped by the silicon, rather than being a ROR instruction. If it wasn't trapped it would be a
    _RET_ ROR 0,0
    which would cause a _RET_ operation following the ROR 0,0 which would have no effect. Wouldn't want that.

    But in P1, anything with the CCCC=0 would become a NOP, so it was often used to hold a smaller variable, or convert an instruction to a NOP.
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • It's not that we don't have a NOP instruction, it's that we don't have a NOP condition.
  • evanhevanh Posts: 8,350
    edited 2019-02-14 - 14:28:12
    It really comes down to COGINIT requiring both a load address of zero and execution to start at zero. ORG has to be aligned to this. If you don't, you make a mess.

    That's why Pasm variables in all Obex programs are at the end.

    PS: You guys are messing up this topic with chatter!
    We have the vastness of the internet and yet billions of people decided to spend most of their time within a horribly designed, fake-news emporium of a website that sucks every possible piece of personal information out of you so it can sell it to others. And they see nothing wrong with that.
  • msrobotsmsrobots Posts: 2,973
    edited 2019-02-14 - 16:23:53
    I like to reuse the top area in the COG where I normally place my startup code as res variables needed later and to store parameter I got from whoever started my COG.

    On the P2 one can do this very efficient.
    DAT
    cog     long  0
    PUB start(param1, param2, param3, param4)
       stop
       cog := cogstart(@entry, @param1) + 1
       
    PUB stop
       if cog
         cogstop(cog-1)
    
    DAT
    entry
            ORG0
    par1    rdlong par1, ptra++
    par2    rdlong par2, ptra++
    par3    rdlong par3, ptra++
    par4    rdlong par4, ptra++
    

    and now my parameter uses the same cog register used by the instruction needed to load the parameter

    you can't do that shorter,

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • Nice one.
  • Cluso99Cluso99 Posts: 15,545
    edited 2019-02-15 - 04:35:26
    Untested, but fairly sure this would work too, and you have 2 instructions to initialise something else.
    DAT
                    org     0
    entry           nop                             ' or something else
                    nop                             ' or something else
                    setq    #4-1
                    rdlong  entry,ptra
    
    Postedit: fixed setq value
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • It should be "setq #3", since the argument of setq in setq+rdlong is how many extra operations it should do, not the total number.
  • TIMEOUT

    Using the counter for timeouts

    Here is how to setup your own timeout
                    getct   timeout                         '\ set timeout value
                    add     timeout,          ##delay1s     '/
    
    and code to test if the timeout has been exceeded
                    getct   timenow                         '\ timeout ?
                    cmpm    timeout,          timenow   wc  '| c if timenow > timeout
            if_c    jmp     #timed_out                      '/ y: timed out          
    
    Note the use of the CMPM D,#/S {wc/wz/wcz} instruction!!!
    C = MSB of the result of D-S

    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • ozpropdevozpropdev Posts: 2,605
    edited 2019-02-22 - 09:20:41
    Timeouts can also be checked using the pollct instructions
                    getct   timeout                         '\ set timeout value
                    addct1     timeout,          ##delay1s     '/
    
    and code to test if the timeout has been exceeded
                    pollct1 wc
            if_c    jmp     #timed_out      
    
    Melbourne, Australia
  • Mark_TMark_T Posts: 1,981
    edited 2019-02-28 - 14:04:32
    One gotcha that regularly catches me out is that fastspin doesn't seem to detect duplicate labels as errors - is there a flag for more warnings?

    [ this is fixed in spin2gui release 1.3.9 and later ]
  • Mark_T wrote: »
    One gotcha that regularly catches me out is that fastspin doesn't seem to detect duplicate labels as errors - is there a flag for more warnings?

    That was a bug; I accidentally commented some error detection code out while debugging. It'll be fixed in the next version.
    FlexGUI, a GUI for programming the P1 and P2 in Spin, PASM, BASIC, and C.
    Help support its development at Patreon or PayPal.
  • I stumbled about another issue, not bad but confusing.

    I can compile a sub-object without errors, but compiling the main object throws then errors in the sub object.

    Maybe you eliminate unused functions to early?

    Enjoy!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • Okay, no more Fastspin bugs/discussions in this topic please. Pnut is okay because it has been frozen for ages.
    We have the vastness of the internet and yet billions of people decided to spend most of their time within a horribly designed, fake-news emporium of a website that sucks every possible piece of personal information out of you so it can sell it to others. And they see nothing wrong with that.
  • Tip: use block reads/writes even for 2 longs:
                setq    #2-1
                rdlong  a, PTRA
                add     PTRA, #8
    
    ' is significantly faster than
    
                rdlong  a, PTRA++
                rdlong  a+1, PTRA++
    

    The issue is you only get synchronous access to the hub with block reads/writes, so the latter version has to wait
    7 cycles as it misses the boat on the second read. Block reads and writes run at one long per clock cycle, ie
    two per instruction time.
  • Cluso99Cluso99 Posts: 15,545
    edited 2019-08-08 - 11:20:25
    Here is a map of the special registers (P1 & P2 compared)
    ''  <------------- P1 ------------->  register  <--------------- P2 ---------------->     
    ''  ---------------------------------------------------------------------------------     
    ''  Boot Parameter              PAR   = $1F0 =  IJMP3  INT3  interrupt call   address     
    ''  System Counter              CNT   = $1F1 =  IRET3  INT3  interrupt return address     
    ''  Input  States     P31..P0   INA   = $1F2 =  IJMP2  INT2  interrupt call   address     
    ''  Input  States     P63..P32  INB   = $1F3 =  IRET2  INT2  interrupt return address     
    ''  Output States     P31..P0   OUTA  = $1F4 =  IJMP1  INT1  interrupt call   address     
    ''  Output States     P63..P32  OUTB  = $1F5 =  IRET1  INT1  interrupt return address     
    ''  Output Enables    P31..P0   DIRA  = $1F6 =  PA     CALLD/CALLPA/LOC                   
    ''  Output Enables    P63..P32  DIRB  = $1F7 =  PB     CALLD/CALLPB/LOC                   
    ''  Counter A Control           CTRA  = $1F8 =  PTRA   pointer A to hub RAM               
    ''  Counter B Control           CTRB  = $1F9 =  PTRB   pointer B to hub RAM               
    ''  Counter A Frequency         FRQA  = $1FA =  DIRA   P31..P0  Output Enables            
    ''  Counter B Frequency         FRQB  = $1FB =  DIRB   P63..P32 Output Enables            
    ''  Counter A Phase             PHSA  = $1FC =  OUTA   P31..P0  Output States             
    ''  Counter B Phase             PHSB  = $1FD =  OUTB   P63..P32 Output States             
    ''  Video Configuration         VCFG  = $1FE =  INA    P31..P0  Input  States  *          (debug interrupt call   address)
    ''  Video Scale                 VSCL  = $1FF =  INB    P63..P32 Input  States  **         (debug interrupt return address)
    ''  ---------------------------------------------------------------------------------     
    
    Postedit: Add debug interrupt call/return addresses
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • Here is a pointer to a discussion of using smart pin mode 00100 (pulse out): (click here)
    Re-inventing the wheel is not a waste of time if, when you are done, you understand why it is round.
  • A trap I ran across: the "altr" setting for writing to the result register (and presumably similar settings like "altd" and "alts") is destroyed by the "aug" prefix. So for example:
       altr 0, #A
       add B, #1
    
    puts B+1 into A, but:
       altr 0, #A
       add B, ##1
    
    puts B+1 into B (!). I thought of breaking the "add B, ##1" apart into an explicit aug+add and putting the altr between them, but since the altr uses an immediate that probably will fail too.

    There are work-arounds, but it's something to watch out for.
    FlexGUI, a GUI for programming the P1 and P2 in Spin, PASM, BASIC, and C.
    Help support its development at Patreon or PayPal.
  • evanhevanh Posts: 8,350
    edited 2019-11-20 - 03:03:07
    A small defect with system clock setting got past the P2ES testing undetected. For clock config word, %0000_xxxE_DDDD_DDMM_MMMM_MMMM_PPPP_CCSS, if a PLL mode is configured with %PPPP = %1111 (_XDIVP = 1) there is a possibility of crashing if attempting to readjust the clock without knowing the exact config it is in.

    One solution, "mailbox hand-off", for reliable operation into the future is to maintain a universal reserved hubRAM location containing a copy of the most recently issued config. That location is currently set as byte addresses $18 to $1b. Little-endian.

    Here is sample code for basic startup that includes the ability for a boot-loader to specify what config it has already set.
    CON
    	XTALFREQ	= 20_000_000                              'PLL stage 0: crystal frequency
    	XDIV		= 2                                       'PLL stage 1: crystal divider
    	XMUL		= 25                                      'PLL stage 2: crystal / div * mul
    	XDIVP		= 1                                       'PLL stage 3: crystal / div * mul / divp (1,2,4..30)
    
    	XOSC		= %10                             'OSC    ' %00=OFF, %01=OSC, %10=15pF, %11=30pF
    	XSEL		= %11                             'XI+PLL ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms)
    	XPPPP		= ((XDIVP>>1) + 15) & $F                  ' 1->15, 2->0, 4->1, 6->2...30->14
    	CLOCKFREQ	= XTALFREQ / XDIV * XMUL / XDIVP
    	SETFREQ		= 1<<24 + (XDIV-1)<<18 + (XMUL-1)<<8 + XPPPP<<4 + XOSC<<2
    	ENAFREQ		= SETFREQ + XSEL                          ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_ss  ' enable oscillator
    
    
    DAT						'not Spin code
    ORGH  0						'loaded to hubram at address 0
    ORG						'longword addressing at 0
    		jmp     #_init
    		long	0,0,0
    '--------------------------------------------------------
    '***  Boot-loader can fill all four of the following  ***
    '--------------------------------------------------------
    spare1		long	0			'hubRAM addr $010 - compatible reserved for system variable
    clk_freq	long	CLOCKFREQ		'hubRAM addr $014 - sysclock frequency, integer frequency in hertz
    clk_mode	long	0			'hubRAM addr $018 - clock mode config word, used directly in HUBSET
    asyn_baud	long	BAUDRATE		'hubRAM addr $01c - comport baud rate, integer baud in hertz
    
    _init
    		andn	clk_mode, #%11		'clear the two select bits to force RCFAST selection
    		hubset	clk_mode		'switch to RCFAST using known prior mode
    		mov	clk_mode, ##SETFREQ	'replace old with new
    		hubset	clk_mode		'setup for new mode, still RCFAST
    		waitx	##25_000_000/100	'~10ms for crystal/PLL to settle
    		hubset	##ENAFREQ		'engage
    		...
    		...
    


    A second solution, "RCFAST hand-off", which is largely compatible with the mailbox hand-off above, can happily co-exist, is to have a convention of always reverting back to RCFAST before launching the loaded program.
    'RCFAST hand-off method in target (loaded) program
    
    _init
    		hubset	##SETFREQ		'setup for new mode, still RCFAST
    		waitx	##25_000_000/100	'~10ms for crystal/PLL to settle
    		hubset	##ENAFREQ		'engage, select PLL as clock source
    		...
    		...
    
    'RCFAST hand-off method in loader program
                    ...
                    andn    clk_mode, #3		'disable XI+PLL mode
                    hubset  clk_mode		'switch to RCFAST mode
                    hubset  #0			'turn off all crystal/PLL modes
                    waitx   ##25_000_000/100	'wait 10 ms for crystal shutdown
    
    		coginit	#0, address		'launch cog 0 from address
    


    Loadp2 has adopted RCFAST hand-off as its default. Mailbox hand-off needs -PATCH option, FlexGUI uses -PATCH.


    EDIT: Ditched all the underscores in the constants to avoid Pnut symbol naming conflict
    (10-3-2019) Improved comments of system variables
    (24-6-2019) Link to original topic - https://forums.parallax.com/discussion/169838/p2-reset-possible-problem/p1
    (18-7-2019) Added ANDN masking for RCFAST clock selection - from Chip's Spin2 interpreter
    (20-11-2019) Belatedly added the simpler RCFAST hand-off option. First suggested by Chip - https://forums.parallax.com/discussion/comment/1474672/#Comment_1474672 and some details at https://forums.parallax.com/discussion/170405/clockfreq-clockmode-and-others-agreement-for-what-and-where
    We have the vastness of the internet and yet billions of people decided to spend most of their time within a horribly designed, fake-news emporium of a website that sucks every possible piece of personal information out of you so it can sell it to others. And they see nothing wrong with that.
  • Nice example, @evanh!

    But PNut throws the error "_CLKFREQ/_XINFREQ specified without _CLKMODE". So it looks like these three words may be reserved.
    garryj
  • clk_freq long _CLKFREQ 'hubRAM addr $014 - integer frequency in hertz

    should be _CLOCKFREQ
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • If using COGATN for synchronisation it's useful to know that the sender cog completes the COGATN instruction two sysclocks earlier than the WAITATN in the receiving cogs.
    We have the vastness of the internet and yet billions of people decided to spend most of their time within a horribly designed, fake-news emporium of a website that sucks every possible piece of personal information out of you so it can sell it to others. And they see nothing wrong with that.
  • Here is a pointer to incmod: click here
    Re-inventing the wheel is not a waste of time if, when you are done, you understand why it is round.
  • I do not believe I am the only follower of this thread who had not seen (or perhaps forgot about) this description of all the P2 Instructions. click here
    Re-inventing the wheel is not a waste of time if, when you are done, you understand why it is round.
  • Getting the 64-bit CNT register
       GETCT A WC
       GETCT B
    

    Chip said...
    It's just for the next instruction (interrupts suspended to read the lower 32bits following reading the top 32bits, and no intervening instructions).
    I think the top 32 bits are two clocks ahead of the lower 32 bits. That's how it winds up time-aligned.

    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • Cluso99Cluso99 Posts: 15,545
    edited 2019-09-16 - 21:53:25
    Here is a summary of the P2 CALL/JMP instructions for V33 RevB silicon
     - Encoding -	"#S = immediate (I=1). S = register.
    #D = immediate (L=1). D = register."	"* Z = (result == 0).
    ** If #S and cogex, PC += signed(S). If #S and hubex, PC += signed(S*4). If S, PC = register S."
    EEEE 1011001 CZI DDDDDDDDD SSSSSSSSS	CALLD   D,{#}S   {WC/WZ/WCZ}	Call to S** by writing {C, Z, 10'b0, PC[19:0]} to D.                    C = S[31], Z = S[30].
    EEEE 1011010 0LI DDDDDDDDD SSSSSSSSS	CALLPA  {#}D,{#}S	Call to S** by pushing {C, Z, 10'b0, PC[19:0]} onto stack, copy D to PA.
    EEEE 1011010 1LI DDDDDDDDD SSSSSSSSS	CALLPB  {#}D,{#}S	Call to S** by pushing {C, Z, 10'b0, PC[19:0]} onto stack, copy D to PB.
    EEEE 1101011 CZ0 DDDDDDDDD 000101101	CALL    D        {WC/WZ/WCZ}	Call to D by pushing {C, Z, 10'b0, PC[19:0]} onto stack.                C = D[31], Z = D[30], PC = D[19:0].
    EEEE 1101011 CZ0 DDDDDDDDD 000101110	CALLA   D        {WC/WZ/WCZ}	Call to D by writing {C, Z, 10'b0, PC[19:0]} to hub long at PTRA++.     C = D[31], Z = D[30], PC = D[19:0].
    EEEE 1101011 CZ0 DDDDDDDDD 000101111	CALLB   D        {WC/WZ/WCZ}	Call to D by writing {C, Z, 10'b0, PC[19:0]} to hub long at PTRB++.     C = D[31], Z = D[30], PC = D[19:0].
    EEEE 1101101 RAA AAAAAAAAA AAAAAAAAA	CALL    #A	Call to A by pushing {C, Z, 10'b0, PC[19:0]} onto stack.                    If R = 1, PC += A, else PC = A.
    EEEE 1101110 RAA AAAAAAAAA AAAAAAAAA	CALLA   #A	Call to A by writing {C, Z, 10'b0, PC[19:0]} to hub long at PTRA++.         If R = 1, PC += A, else PC = A.
    EEEE 1101111 RAA AAAAAAAAA AAAAAAAAA	CALLB   #A	Call to A by writing {C, Z, 10'b0, PC[19:0]} to hub long at PTRB++.         If R = 1, PC += A, else PC = A.
    EEEE 11100WW RAA AAAAAAAAA AAAAAAAAA	CALLD   PA/PB/PTRA/PTRB,#A	Call to A by writing {C, Z, 10'b0, PC[19:0]} to PA/PB/PTRA/PTRB (per W).    If R = 1, PC += A, else PC = A.
    		
    0000 ------- --- --------- ---------	_RET_         <inst>  <ops>	Execute <inst> always and return if no branch. If <inst> is not branching then return by popping stack[19:0] into PC.
    EEEE 1101011 CZ1 000000000 000101101	RET              {WC/WZ/WCZ}	Return by popping stack (K).                                            C = K[31], Z = K[30], PC = K[19:0].
    EEEE 1101011 CZ1 000000000 000101110	RETA             {WC/WZ/WCZ}	Return by reading hub long (L) at --PTRA.                               C = L[31], Z = L[30], PC = L[19:0].
    EEEE 1101011 CZ1 000000000 000101111	RETB             {WC/WZ/WCZ}	Return by reading hub long (L) at --PTRB.                               C = L[31], Z = L[30], PC = L[19:0].
    EEEE 1011001 110 111111111 111110001	RETI3	Return from INT3. (CALLD $1FF,$1F1 WC,WZ)
    EEEE 1011001 110 111111111 111110011	RETI2	Return from INT2. (CALLD $1FF,$1F3 WC,WZ)
    EEEE 1011001 110 111111111 111110101	RETI1	Return from INT1. (CALLD $1FF,$1F5 WC,WZ)
    EEEE 1011001 110 111111111 111111111	RETI0	Return from INT0. (CALLD $1FF,$1FF WC,WZ)
    EEEE 1011001 110 111110000 111110001	RESI3	Resume from INT3. (CALLD $1F0,$1F1 WC,WZ)
    EEEE 1011001 110 111110010 111110011	RESI2	Resume from INT2. (CALLD $1F2,$1F3 WC,WZ)
    EEEE 1011001 110 111110100 111110101	RESI1	Resume from INT1. (CALLD $1F4,$1F5 WC,WZ)
    EEEE 1011001 110 111111110 111111111	RESI0	Resume from INT0. (CALLD $1FE,$1FF WC,WZ)
    		
    EEEE 1101011 CZ0 DDDDDDDDD 000101100	JMP     D        {WC/WZ/WCZ}	Jump to D.                                                              C = D[31], Z = D[30], PC = D[19:0].
    EEEE 1101011 00L DDDDDDDDD 000110000	JMPREL  {#}D	Jump ahead/back by D instructions. For cogex, PC += D[19:0]. For hubex, PC += D[17:0] << 2.
    EEEE 1101100 RAA AAAAAAAAA AAAAAAAAA	JMP     #A	Jump to A.                                                                  If R = 1, PC += A, else PC = A.
    		
    EEEE 1011011 00I DDDDDDDDD SSSSSSSSS	DJZ     D,{#}S	Decrement D and jump to S** if result is zero.
    EEEE 1011011 01I DDDDDDDDD SSSSSSSSS	DJNZ    D,{#}S	Decrement D and jump to S** if result is not zero.
    EEEE 1011011 10I DDDDDDDDD SSSSSSSSS	DJF     D,{#}S	Decrement D and jump to S** if result is $FFFF_FFFF.
    EEEE 1011011 11I DDDDDDDDD SSSSSSSSS	DJNF    D,{#}S	Decrement D and jump to S** if result is not $FFFF_FFFF.
    EEEE 1011100 00I DDDDDDDDD SSSSSSSSS	IJZ     D,{#}S	Increment D and jump to S** if result is zero.
    EEEE 1011100 01I DDDDDDDDD SSSSSSSSS	IJNZ    D,{#}S	Increment D and jump to S** if result is not zero.
    EEEE 1011100 10I DDDDDDDDD SSSSSSSSS	TJZ     D,{#}S	Test D and jump to S** if D is zero.
    EEEE 1011100 11I DDDDDDDDD SSSSSSSSS	TJNZ    D,{#}S	Test D and jump to S** if D is not zero.
    EEEE 1011101 00I DDDDDDDDD SSSSSSSSS	TJF     D,{#}S	Test D and jump to S** if D is full (D = $FFFF_FFFF).
    EEEE 1011101 01I DDDDDDDDD SSSSSSSSS	TJNF    D,{#}S	Test D and jump to S** if D is not full (D != $FFFF_FFFF).
    EEEE 1011101 10I DDDDDDDDD SSSSSSSSS	TJS     D,{#}S	Test D and jump to S** if D is signed (D[31] = 1).
    EEEE 1011101 11I DDDDDDDDD SSSSSSSSS	TJNS    D,{#}S	Test D and jump to S** if D is not signed (D[31] = 0).
    EEEE 1011110 00I DDDDDDDDD SSSSSSSSS	TJV     D,{#}S	Test D and jump to S** if D overflowed (D[31] != C, C = 'correct sign' from last addition/subtraction).
    		
    EEEE 1011110 01I 000000000 SSSSSSSSS	JINT    {#}S	Jump to S** if INT event flag is set.
    EEEE 1011110 01I 000000001 SSSSSSSSS	JCT1    {#}S	Jump to S** if CT1 event flag is set.
    EEEE 1011110 01I 000000010 SSSSSSSSS	JCT2    {#}S	Jump to S** if CT2 event flag is set.
    EEEE 1011110 01I 000000011 SSSSSSSSS	JCT3    {#}S	Jump to S** if CT3 event flag is set.
    EEEE 1011110 01I 000000100 SSSSSSSSS	JSE1    {#}S	Jump to S** if SE1 event flag is set.
    EEEE 1011110 01I 000000101 SSSSSSSSS	JSE2    {#}S	Jump to S** if SE2 event flag is set.
    EEEE 1011110 01I 000000110 SSSSSSSSS	JSE3    {#}S	Jump to S** if SE3 event flag is set.
    EEEE 1011110 01I 000000111 SSSSSSSSS	JSE4    {#}S	Jump to S** if SE4 event flag is set.
    EEEE 1011110 01I 000001000 SSSSSSSSS	JPAT    {#}S	Jump to S** if PAT event flag is set.
    EEEE 1011110 01I 000001001 SSSSSSSSS	JFBW    {#}S	Jump to S** if FBW event flag is set.
    EEEE 1011110 01I 000001010 SSSSSSSSS	JXMT    {#}S	Jump to S** if XMT event flag is set.
    EEEE 1011110 01I 000001011 SSSSSSSSS	JXFI    {#}S	Jump to S** if XFI event flag is set.
    EEEE 1011110 01I 000001100 SSSSSSSSS	JXRO    {#}S	Jump to S** if XRO event flag is set.
    EEEE 1011110 01I 000001101 SSSSSSSSS	JXRL    {#}S	Jump to S** if XRL event flag is set.
    EEEE 1011110 01I 000001110 SSSSSSSSS	JATN    {#}S	Jump to S** if ATN event flag is set.
    EEEE 1011110 01I 000001111 SSSSSSSSS	JQMT    {#}S	Jump to S** if QMT event flag is set.
    EEEE 1011110 01I 000010000 SSSSSSSSS	JNINT   {#}S	Jump to S** if INT event flag is clear.
    EEEE 1011110 01I 000010001 SSSSSSSSS	JNCT1   {#}S	Jump to S** if CT1 event flag is clear.
    EEEE 1011110 01I 000010010 SSSSSSSSS	JNCT2   {#}S	Jump to S** if CT2 event flag is clear.
    EEEE 1011110 01I 000010011 SSSSSSSSS	JNCT3   {#}S	Jump to S** if CT3 event flag is clear.
    EEEE 1011110 01I 000010100 SSSSSSSSS	JNSE1   {#}S	Jump to S** if SE1 event flag is clear.
    EEEE 1011110 01I 000010101 SSSSSSSSS	JNSE2   {#}S	Jump to S** if SE2 event flag is clear.
    EEEE 1011110 01I 000010110 SSSSSSSSS	JNSE3   {#}S	Jump to S** if SE3 event flag is clear.
    EEEE 1011110 01I 000010111 SSSSSSSSS	JNSE4   {#}S	Jump to S** if SE4 event flag is clear.
    EEEE 1011110 01I 000011000 SSSSSSSSS	JNPAT   {#}S	Jump to S** if PAT event flag is clear.
    EEEE 1011110 01I 000011001 SSSSSSSSS	JNFBW   {#}S	Jump to S** if FBW event flag is clear.
    EEEE 1011110 01I 000011010 SSSSSSSSS	JNXMT   {#}S	Jump to S** if XMT event flag is clear.
    EEEE 1011110 01I 000011011 SSSSSSSSS	JNXFI   {#}S	Jump to S** if XFI event flag is clear.
    EEEE 1011110 01I 000011100 SSSSSSSSS	JNXRO   {#}S	Jump to S** if XRO event flag is clear.
    EEEE 1011110 01I 000011101 SSSSSSSSS	JNXRL   {#}S	Jump to S** if XRL event flag is clear.
    EEEE 1011110 01I 000011110 SSSSSSSSS	JNATN   {#}S	Jump to S** if ATN event flag is clear.
    EEEE 1011110 01I 000011111 SSSSSSSSS	JNQMT   {#}S	Jump to S** if QMT event flag is clear.
    		
    EEEE 1101011 00L DDDDDDDDD 000110001	SKIP    {#}D	Skip instructions per D. Subsequent instructions 0..31 get cancelled for each '1' bit in D[0]..D[31].
    EEEE 1101011 00L DDDDDDDDD 000110010	SKIPF   {#}D	Skip cog/LUT instructions fast per D. Like SKIP, but instead of cancelling instructions, the PC leaps over them.
    EEEE 1101011 00L DDDDDDDDD 000110011	EXECF   {#}D	Jump to D[9:0] in cog/LUT and set SKIPF pattern to D[31:10]. PC = {10'b0, D[9:0]}.
    
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • Cluso99Cluso99 Posts: 15,545
    edited 2019-09-19 - 04:04:29
    Special SKIPF Branching Rules
    From the manual...
    Within SKIPF sequences where CALL/CALLPA/CALLPB are used to execute subroutines in which skipping will be suspended until after RET, all CALL/CALLPA/CALLPB immediate branch addresses must be absolute in cases where the instruction after the CALL/CALLPA/CALLPB might be skipped. This is not possible for CALLPA/CALLPB but CALL can use '#\address' syntax to achieve absolute immediate addressing. CALL/CALLPA/CALLPB can all use registers as branch addresses, since they are absolute.

    For non-CALL\CALLPA\CALLPB branches within SKIPF sequences, SKIPF will work through all immediate-relative branches, which are the default for immediate branches within cog/LUT memory. If an absolute-address branch is being used (#\label, register, or RET, for example), you must not skip the first instruction after the branch. This is not a problem with immediate-relative branches, however, since the variable PC stepping works to advantage, by landing the PC at the first instruction of interest at, or beyond, the branch address.
    Refer here forums.parallax.com/discussion/comment/1478399/#Comment_1478399 for further discussion (please keep this thread free from discussion)
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • BITNOT with the WCZ operation is simple neat instruction for flipping a single routine between two modes.
    We have the vastness of the internet and yet billions of people decided to spend most of their time within a horribly designed, fake-news emporium of a website that sucks every possible piece of personal information out of you so it can sell it to others. And they see nothing wrong with that.
  • Cluso99Cluso99 Posts: 15,545
    edited 2019-11-18 - 19:58:10
    P2 ROM Boot Sequence vs Pullups/Pulldowns
    (using the Rom source code)
    P2%20Boot%20Sequence.jpg
    407 x 200 - 40K
    My Prop boards: P8XBlade2 , RamBlade , CpuBlade , TriBlade
    P1 Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    P1: Tools (Index) , Emulators (Index) , ZiCog (Z80)
    P2: Tools & Code , Tricks & Traps
  • SPAN IO pins feature

    From the docs
    DIRx/OUTx/FLTx/DRVx can now work on a span of pins (+D[10:6] pins).
    Prior SETQ overrides D[10:6].

    WRPIN/WXPIN/WYPIN/AKPIN can now work on a span of pins (+S[10:6] pins).
    Prior SETQ overrides S[10:6].

    Be aware that this feature cannpnt cross the PinA/PinB boundary and
    wraps within the 32 pin group.

    For example the following code configures pins 30,31,0,1 not 30,31,32,33
    		setq	#3
    		wrpin	##%011_00_00000_0,#30 '150k pulldown
    		setq	#3
    		drvl	#30 
    
    Melbourne, Australia
Sign In or Register to comment.