Shop OBEX P1 Docs P2 Docs Learn Events
Propeller II update - BLOG - Page 217 — Parallax Forums

Propeller II update - BLOG

1214215217219220223

Comments

  • ozpropdevozpropdev Posts: 2,793
    edited 2014-03-20 05:20
    mindrobots wrote: »
    Party pooper!! :lol:

    Thanks! I was going to do the same thing with your handy dandy tool!

    Sorry Rick! I already had the output ready to go and hadn't posted it. :lol:
    You have the next one! :lol:
    Cheers
    Brian
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 07:17
    THANKS CHIP!!!!

    This time, I will make time to play!

    Now I just have to remember how to load my DE2-115... it has been a while.
    cgracey wrote: »
    Okay. Here is the intermediate release. Its documentation will be getting updated over the next few days. So, at first, you are on your own, needing to infer things from the instruction list in Prop2_Docs.txt, which IS accurate. Of course, you can ask any questions here on the forum and I'll answer them.


    The DE0-Nano FPGA configuration lacks the following, in order to make one cog fit:

    CTRB - 2nd counter (CTRA is complete, including waveform output)
    SERB - 2nd serial port
    CORDIC - qsincos/qarctan/qrotate/qlog/qexp
    PIX - texture mapping, pixel blending


    Here's the file:

    Attachment not found.


    Here's the new instruction set:
    ZCDS (for D column: W=write, M=modify, R=read, L=read/immediate)
    ----------------------------------------------------------------------------------------------------------------------
    ZCWS		0000000 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDBYTE	D,S/PTRA/PTRB		(waits for hub)
    ZCWS		0000001 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDBYTEC	D,S/PTRA/PTRB		(waits for hub if dcache miss)
    ZCWS		0000010 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDWORD	D,S/PTRA/PTRB		(waits for hub)
    ZCWS		0000011 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDWORDC	D,S/PTRA/PTRB		(waits for hub if dcache miss)
    ZCWS		0000100 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDLONG	D,S/PTRA/PTRB		(waits for hub)
    ZCWS		0000101 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDLONGC	D,S/PTRA/PTRB		(waits for hub if dcache miss)
    ZCWS		0000110 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDAUX	D,S/#0..$FF/PTRX/PTRY
    ZCWS		0000111 ZC I CCCC DDDDDDDDD SSSSSSSSS		RDAUXR	D,S/#0..$FF/PTRX/PTRY
    
    ZCMS		0001000 ZC I CCCC DDDDDDDDD SSSSSSSSS		ISOB	D,S/#
    ZCMS		0001001 ZC I CCCC DDDDDDDDD SSSSSSSSS		NOTB	D,S/#
    ZCMS		0001010 ZC I CCCC DDDDDDDDD SSSSSSSSS		CLRB	D,S/#
    ZCMS		0001011 ZC I CCCC DDDDDDDDD SSSSSSSSS		SETB	D,S/#
    ZCMS		0001100 ZC I CCCC DDDDDDDDD SSSSSSSSS		SETBC	D,S/#
    ZCMS		0001101 ZC I CCCC DDDDDDDDD SSSSSSSSS		SETBNC	D,S/#
    ZCMS		0001110 ZC I CCCC DDDDDDDDD SSSSSSSSS		SETBZ	D,S/#
    ZCMS		0001111 ZC I CCCC DDDDDDDDD SSSSSSSSS		SETBNZ	D,S/#
    
    ZCMS		0010000 ZC I CCCC DDDDDDDDD SSSSSSSSS		ANDN	D,S/#
    ZCMS		0010001 ZC I CCCC DDDDDDDDD SSSSSSSSS		AND	D,S/#
    ZCMS		0010010 ZC I CCCC DDDDDDDDD SSSSSSSSS		OR	D,S/#
    ZCMS		0010011 ZC I CCCC DDDDDDDDD SSSSSSSSS		XOR	D,S/#
    ZCMS		0010100 ZC I CCCC DDDDDDDDD SSSSSSSSS		MUXC	D,S/#
    ZCMS		0010101 ZC I CCCC DDDDDDDDD SSSSSSSSS		MUXNC	D,S/#
    ZCMS		0010110 ZC I CCCC DDDDDDDDD SSSSSSSSS		MUXZ	D,S/#
    ZCMS		0010111 ZC I CCCC DDDDDDDDD SSSSSSSSS		MUXNZ	D,S/#
    
    ZCMS		0011000 ZC I CCCC DDDDDDDDD SSSSSSSSS		ROR	D,S/#
    ZCMS		0011001 ZC I CCCC DDDDDDDDD SSSSSSSSS		ROL	D,S/#
    ZCMS		0011010 ZC I CCCC DDDDDDDDD SSSSSSSSS		SHR	D,S/#
    ZCMS		0011011 ZC I CCCC DDDDDDDDD SSSSSSSSS		SHL	D,S/#
    ZCMS		0011100 ZC I CCCC DDDDDDDDD SSSSSSSSS		RCR	D,S/#
    ZCMS		0011101 ZC I CCCC DDDDDDDDD SSSSSSSSS		RCL	D,S/#
    ZCMS		0011110 ZC I CCCC DDDDDDDDD SSSSSSSSS		SAR	D,S/#
    ZCMS		0011111 ZC I CCCC DDDDDDDDD SSSSSSSSS		REV	D,S/#
    
    ZCWS		0100000 ZC I CCCC DDDDDDDDD SSSSSSSSS		MOV	D,S/#
    ZCWS		0100001 ZC I CCCC DDDDDDDDD SSSSSSSSS		NOT	D,S/#
    ZCWS		0100010 ZC I CCCC DDDDDDDDD SSSSSSSSS		ABS	D,S/#
    ZCWS		0100011 ZC I CCCC DDDDDDDDD SSSSSSSSS		NEG	D,S/#
    ZCWS		0100100 ZC I CCCC DDDDDDDDD SSSSSSSSS		NEGC	D,S/#
    ZCWS		0100101 ZC I CCCC DDDDDDDDD SSSSSSSSS		NEGNC	D,S/#
    ZCWS		0100110 ZC I CCCC DDDDDDDDD SSSSSSSSS		NEGZ	D,S/#
    ZCWS		0100111 ZC I CCCC DDDDDDDDD SSSSSSSSS		NEGNZ	D,S/#
    
    ZCMS		0101000 ZC I CCCC DDDDDDDDD SSSSSSSSS		ADD	D,S/#
    ZCMS		0101001 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUB	D,S/#
    ZCMS		0101010 ZC I CCCC DDDDDDDDD SSSSSSSSS		ADDX	D,S/#
    ZCMS		0101011 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUBX	D,S/#
    ZCMS		0101100 ZC I CCCC DDDDDDDDD SSSSSSSSS		ADDS	D,S/#
    ZCMS		0101101 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUBS	D,S/#
    ZCMS		0101110 ZC I CCCC DDDDDDDDD SSSSSSSSS		ADDSX	D,S/#
    ZCMS		0101111 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUBSX	D,S/#
    
    ZCMS		0110000 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUMC	D,S/#
    ZCMS		0110001 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUMNC	D,S/#
    ZCMS		0110010 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUMZ	D,S/#
    ZCMS		0110011 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUMNZ	D,S/#
    ZCMS		0110100 ZC I CCCC DDDDDDDDD SSSSSSSSS		MIN	D,S/#
    ZCMS		0110101 ZC I CCCC DDDDDDDDD SSSSSSSSS		MAX	D,S/#
    ZCMS		0110110 ZC I CCCC DDDDDDDDD SSSSSSSSS		MINS	D,S/#
    ZCMS		0110111 ZC I CCCC DDDDDDDDD SSSSSSSSS		MAXS	D,S/#
    
    ZCMS		0111000 ZC I CCCC DDDDDDDDD SSSSSSSSS		ADDABS	D,S/#
    ZCMS		0111001 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUBABS	D,S/#
    ZCMS		0111010 ZC I CCCC DDDDDDDDD SSSSSSSSS		INCMOD	D,S/#
    ZCMS		0111011 ZC I CCCC DDDDDDDDD SSSSSSSSS		DECMOD	D,S/#
    ZCMS		0111100 ZC I CCCC DDDDDDDDD SSSSSSSSS		CMPSUB	D,S/#
    ZCMS		0111101 ZC I CCCC DDDDDDDDD SSSSSSSSS		SUBR	D,S/#
    ZCMS		0111110 ZC I CCCC DDDDDDDDD SSSSSSSSS		MUL	D,S/#			(takes two clocks)
    ZCMS		0111111 ZC I CCCC DDDDDDDDD SSSSSSSSS		SCL	D,S/#			(takes two clocks)
    
    ZCWS		1000000 ZC I CCCC DDDDDDDDD SSSSSSSSS		DECOD2	D,S/#
    ZCWS		1000001 ZC I CCCC DDDDDDDDD SSSSSSSSS		DECOD3	D,S/#
    ZCWS		1000010 ZC I CCCC DDDDDDDDD SSSSSSSSS		DECOD4	D,S/#
    ZCWS		1000011 ZC I CCCC DDDDDDDDD SSSSSSSSS		DECOD5	D,S/#
    Z-WS		1000100 Z0 I CCCC DDDDDDDDD SSSSSSSSS		BLSIZE	D,S/#
    Z-WS		1000100 Z1 I CCCC DDDDDDDDD SSSSSSSSS		BLMASK	D,S/#
    Z-WS		1000101 Z0 I CCCC DDDDDDDDD SSSSSSSSS		ONECNT	D,S/#			(takes two clocks)
    Z-WS		1000101 Z1 I CCCC DDDDDDDDD SSSSSSSSS		ZERCNT	D,S/#			(takes two clocks)
    ZCWS		1000110 0C I CCCC DDDDDDDDD SSSSSSSSS		TOPONE	D,S/#			(takes two clocks)
    ZCWS		1000110 1C I CCCC DDDDDDDDD SSSSSSSSS		TOPZER	D,S/#			(takes two clocks)
    ZCWS		1000111 0C I CCCC DDDDDDDDD SSSSSSSSS		BOTONE	D,S/#			(takes two clocks)
    ZCWS		1000111 1C I CCCC DDDDDDDDD SSSSSSSSS		BOTZER	D,S/#			(takes two clocks)
    
    --MS		10010nn n0 I CCCC DDDDDDDDD SSSSSSSSS		GETNIB	D,S/#,#0..7
    --MS		10010nn n1 I CCCC DDDDDDDDD SSSSSSSSS		SETNIB	D,S/#,#0..7
    --MS		1001100 n0 I CCCC DDDDDDDDD SSSSSSSSS		GETWORD	D,S/#,#0..1
    --MS		1001100 n1 I CCCC DDDDDDDDD SSSSSSSSS		SETWORD	D,S/#,#0..1
    --MS		1001101 00 I CCCC DDDDDDDDD SSSSSSSSS		ROLNIB	D,S/#
    --MS		1001101 01 I CCCC DDDDDDDDD SSSSSSSSS		ROLBYTE	D,S/#
    --MS		1001101 10 I CCCC DDDDDDDDD SSSSSSSSS		ROLWORD	D,S/#
    --MS		1001101 11 I CCCC DDDDDDDDD SSSSSSSSS		SETS	D,S/#
    --MS		1001110 00 I CCCC DDDDDDDDD SSSSSSSSS		SETD	D,S/#
    --MS		1001110 01 I CCCC DDDDDDDDD SSSSSSSSS		SETCOND	D,S/#
    --MS		1001110 10 I CCCC DDDDDDDDD SSSSSSSSS		SETINST	D,S/#
    --MS		1001110 11 I CCCC DDDDDDDDD SSSSSSSSS		THALT	D,S/#
    -CMS		1001111 0C I CCCC DDDDDDDDD SSSSSSSSS		WAITCNT	D,S/#			(waits for CNT, +CNTX if WC)
    --MS		1001111 10 I CCCC DDDDDDDDD SSSSSSSSS		<empty>	D,S/#
    --RS		1001111 11 I CCCC DDDDDDDDD SSSSSSSSS		PICKZC	D,S/#			(always writes Z/C)
    
    --MS		101000n n0 I CCCC DDDDDDDDD SSSSSSSSS		GETBYTE	D,S/#,#0..3
    --MS		101000n n1 I CCCC DDDDDDDDD SSSSSSSSS		SETBYTE	D,S/#,#0..3
    --WS		1010010 00 I CCCC DDDDDDDDD SSSSSSSSS		SETBYTS	D,S/#
    --MS		1010010 01 I CCCC DDDDDDDDD SSSSSSSSS		MOVBYTS	D,S/#			(move bytes in D, S = %11_10_01_00 = D same)
    --MS		1010010 10 I CCCC DDDDDDDDD SSSSSSSSS		PACKRGB	D,S/#			(S 8:8:8 -> D 5:5:5 << 16 | D >> 16)
    --WS		1010010 11 I CCCC DDDDDDDDD SSSSSSSSS		UNPKRGB	D,S/#			(S 5:5:5 -> D 8:8:8)
    --MS		1010011 00 I CCCC DDDDDDDDD SSSSSSSSS		ADDPIX	D,S/#			(takes two clocks)
    --MS		1010011 01 I CCCC DDDDDDDDD SSSSSSSSS		MULPIX	D,S/#			(takes two clocks)
    --MS		1010011 10 I CCCC DDDDDDDDD SSSSSSSSS		BLNPIX	D,S/#			(takes two clocks)
    --MS		1010011 11 I CCCC DDDDDDDDD SSSSSSSSS		MIXPIX	D,S/#			(takes two clocks)
    
    ZCMS		1010100 ZC I CCCC DDDDDDDDD SSSSSSSSS		JMPSW	D,S/@
    ZCMS		1010101 ZC I CCCC DDDDDDDDD SSSSSSSSS		JMPSWD	D,S/@
    --MS		1010110 00 I CCCC DDDDDDDDD SSSSSSSSS		DJZ	D,S/@
    --MS		1010110 01 I CCCC DDDDDDDDD SSSSSSSSS		DJZD	D,S/@
    --MS		1010110 10 I CCCC DDDDDDDDD SSSSSSSSS		DJNZ	D,S/@
    --MS		1010110 11 I CCCC DDDDDDDDD SSSSSSSSS		DJNZD	D,S/@
    --RS		1010111 00 I CCCC DDDDDDDDD SSSSSSSSS		JZ	D,S/@
    --RS		1010111 01 I CCCC DDDDDDDDD SSSSSSSSS		JZD	D,S/@
    --RS		1010111 10 I CCCC DDDDDDDDD SSSSSSSSS		JNZ	D,S/@
    --RS		1010111 11 I CCCC DDDDDDDDD SSSSSSSSS		JNZD	D,S/@
    
    ZCRS		1011000 ZC I CCCC DDDDDDDDD SSSSSSSSS		TESTB	D,S/#
    ZCRS		1011001 ZC I CCCC DDDDDDDDD SSSSSSSSS		TESTN	D,S/#
    ZCRS		1011010 ZC I CCCC DDDDDDDDD SSSSSSSSS		TEST	D,S/#
    ZCRS		1011011 ZC I CCCC DDDDDDDDD SSSSSSSSS		CMP	D,S/#
    ZCRS		1011100 ZC I CCCC DDDDDDDDD SSSSSSSSS		CMPX	D,S/#
    ZCRS		1011101 ZC I CCCC DDDDDDDDD SSSSSSSSS		CMPS	D,S/#
    ZCRS		1011110 ZC I CCCC DDDDDDDDD SSSSSSSSS		CMPSX	D,S/#
    ZCRS		1011111 ZC I CCCC DDDDDDDDD SSSSSSSSS		CMPR	D,S/#
    
    -CRS		110000n nC I CCCC DDDDDDDDD SSSSSSSSS		WAITPEQ	D,S/#,#0..3		(waits for pins, plus CNT if WC)
    -CRS		110001n nC I CCCC DDDDDDDDD SSSSSSSSS		WAITPNE	D,S/#,#0..3		(waits for pins, plus CNT if WC)
    ---S		110010n nn I CCCC nnnnnnnnn SSSSSSSSS		WAITVID	#0..$DFF,S/#		(waits for vid if single-task, loops if multi-task)
    --RS		1100101 11 I CCCC DDDDDDDDD SSSSSSSSS		WAITVID	D,S/#			(waits for vid if single-task, loops if multi-task)
    --LS		1100110 0L I CCCC DDDDDDDDD SSSSSSSSS		WRBYTE	D/#,S/PTRA/PTRB		(waits for hub)
    --LS		1100110 1L I CCCC DDDDDDDDD SSSSSSSSS		WRWORD	D/#,S/PTRA/PTRB		(waits for hub)
    --LS		1100111 0L I CCCC DDDDDDDDD SSSSSSSSS		WRLONG	D/#,S/PTRA/PTRB		(waits for hub)
    --LS		1100111 1L I CCCC DDDDDDDDD SSSSSSSSS		WRWIDEM	D/#,S/PTRA/PTRB		(waits for hub) D = write mask, where 1 bits mean 'don't-write'
    --LS		1100111 11 I CCCC 000000000 SSSSSSSSS		WRWIDE	S/PTRA/PTRB		(waits for hub) D = constant $00000000, so all bytes written
    
    --LS		1101000 0L I CCCC DDDDDDDDD SSSSSSSSS		WRAUX	D/#,S/#0..$FF/PTRX/PTRY
    --LS		1101000 1L I CCCC DDDDDDDDD SSSSSSSSS		WRAUXR	D/#,S/#0..$FF/PTRX/PTRY
    --LS		1101001 0L I CCCC DDDDDDDDD SSSSSSSSS		SETACCA	D/#,S/#
    --LS		1101001 1L I CCCC DDDDDDDDD SSSSSSSSS		SETACCB	D/#,S/#
    --LS		1101010 0L I CCCC DDDDDDDDD SSSSSSSSS		MACA	D/#,S/#
    --LS		1101010 1L I CCCC DDDDDDDDD SSSSSSSSS		MACB	D/#,S/#
    --LS		1101011 0L I CCCC DDDDDDDDD SSSSSSSSS		MUL32	D/#,S/#
    --LS		1101011 1L I CCCC DDDDDDDDD SSSSSSSSS		MUL32U	D/#,S/#
    --LS		1101100 0L I CCCC DDDDDDDDD SSSSSSSSS		DIV32	D/#,S/#
    --LS		1101100 1L I CCCC DDDDDDDDD SSSSSSSSS		DIV32U	D/#,S/#
    --LS		1101101 0L I CCCC DDDDDDDDD SSSSSSSSS		DIV64	D/#,S/#
    --LS		1101101 1L I CCCC DDDDDDDDD SSSSSSSSS		DIV64U	D/#,S/#
    --LS		1101110 0L I CCCC DDDDDDDDD SSSSSSSSS		SQRT64	D/#,S/#
    --LS		1101110 1L I CCCC DDDDDDDDD SSSSSSSSS		QSINCOS	D/#,S/#
    --LS		1101111 0L I CCCC DDDDDDDDD SSSSSSSSS		QARCTAN	D/#,S/#
    --LS		1101111 1L I CCCC DDDDDDDDD SSSSSSSSS		QROTATE	D/#,S/#
    
    --LS		111000n nL I CCCC DDDDDDDDD SSSSSSSSS		CFGPINS	D/#,S/#,#0..2		(waits for alt)
    --LS		1110001 1L I CCCC DDDDDDDDD SSSSSSSSS		SETMAP	D/#,S/#
    --LS		1110010 0L I CCCC DDDDDDDDD SSSSSSSSS		SETSERA	D/#,S/#			(config,baud)
    --LS		1110010 1L I CCCC DDDDDDDDD SSSSSSSSS		SETSERB	D/#,S/#			(config,baud)
    --LS		1110011 0L I CCCC DDDDDDDDD SSSSSSSSS		SETCTRS	D/#,S/#			(ctrb,ctra)
    --LS		1110011 1L I CCCC DDDDDDDDD SSSSSSSSS		SETWAVS	D/#,S/#			(ctrb,ctra)
    --LS		1110100 0L I CCCC DDDDDDDDD SSSSSSSSS		SETFRQS	D/#,S/#			(ctrb,ctra)
    --LS		1110100 1L I CCCC DDDDDDDDD SSSSSSSSS		SETPHSS	D/#,S/#			(ctrb,ctra)
    --LS		1110101 0L I CCCC DDDDDDDDD SSSSSSSSS		ADDPHSS	D/#,S/#			(ctrb,ctra)
    --LS		1110101 1L I CCCC DDDDDDDDD SSSSSSSSS		SUBPHSS	D/#,S/#			(ctrb,ctra)
    --LS		1110110 0L I CCCC DDDDDDDDD SSSSSSSSS		SETXFR	D/#,S/#
    --LS		1110110 1L I CCCC DDDDDDDDD SSSSSSSSS		SETMIX	D/#,S/#
    --LS		1110111 0L I CCCC DDDDDDDDD SSSSSSSSS		COGRUN	D/#,S/#			(waits for hub)
    --LS		1110111 1L I CCCC DDDDDDDDD SSSSSSSSS		COGRUNX	D/#,S/#			(waits for hub)
    
    --LS		1111000 0L I CCCC DDDDDDDDD SSSSSSSSS		FRAC	D/#,S/#
    --LS		1111000 1L I CCCC DDDDDDDDD SSSSSSSSS		LODINDS	D/#,S/#
    --LS		1111001 0L I CCCC DDDDDDDDD SSSSSSSSS		CIRINDA	D/#,S/#
    --LS		1111001 1L I CCCC DDDDDDDDD SSSSSSSSS		CIRINDB	D/#,S/#
    --LS		1111010 0L I CCCC DDDDDDDDD SSSSSSSSS		JP	D/#,S/@			(takes two clocks)
    --LS		1111010 1L I CCCC DDDDDDDDD SSSSSSSSS		JPD	D/#,S/@			(takes two clocks)
    --LS		1111011 0L I CCCC DDDDDDDDD SSSSSSSSS		JNP	D/#,S/@			(takes two clocks)
    --LS		1111011 1L I CCCC DDDDDDDDD SSSSSSSSS		JNPD	D/#,S/@			(takes two clocks)
    
    --WS		1111100 00 I CCCC DDDDDDDDD SSSSSSSSS		LOCBASE	D,S/@			(if S:        S<<2, if @S:        (P+@S)<<2)
    --MS		1111100 01 I CCCC DDDDDDDDD SSSSSSSSS		LOCBYTE	D,S/@			(if S: D<<0 + S<<2, if @S: D<<0 + (P+@S)<<2)
    --MS		1111100 10 I CCCC DDDDDDDDD SSSSSSSSS		LOCWORD	D,S/@			(if S: D<<1 + S<<2, if @S: D<<1 + (P+@S)<<2)
    --MS		1111100 11 I CCCC DDDDDDDDD SSSSSSSSS		LOCLONG	D,S/@			(if S: D<<2 + S<<2, if @S: D<<2 + (P+@S)<<2)
    
    --W-		1111101 00 0 CCCC DDDDDDDDD sssssssss		LOCINST	D,@s			(P+s)
    --R-		1111101 00 1 CCCC DDDDDDDDD sssssssss		JMPLIST	D,@s			(jump to P+s+D)
    
    ----		1111101 01 0 BBAA ddddddddd sssssssss		FIXINDA #d,#s / FIXINDB #d,#s / FIXINDS #d,#s / SETINDA #s / SETINDB #d / SETINDS #d,#s
    ----		1111101 01 1 nnnn nnnnnnnnn nnniiiiii		REPS	#1..$10000,#1..64
    
    ----		1111101 10 n nnnn nnnnnnnnn nnnnnnnnn		AUGS	#23bits			(appends n to upper bits of next immediate S)
    ----		1111101 11 n nnnn nnnnnnnnn nnnnnnnnn		AUGD	#23bits			(appends n to upper bits of next immediate D)
    
    ----		1111110 00 0 CCCC 00 nnnnnnnnnnnnnnnn		LOCPTRA	#abs
    ----		1111110 00 0 CCCC 01 nnnnnnnnnnnnnnnn		LOCPTRA	@rel
    ----		1111110 00 0 CCCC 10 nnnnnnnnnnnnnnnn		LOCPTRB	#abs
    ----		1111110 00 0 CCCC 11 nnnnnnnnnnnnnnnn		LOCPTRB	@rel
    
    ----		1111110 00 1 CCCC 00 nnnnnnnnnnnnnnnn		JMP	#abs
    ----		1111110 00 1 CCCC 01 nnnnnnnnnnnnnnnn		JMP	@rel
    ----		1111110 00 1 CCCC 10 nnnnnnnnnnnnnnnn		JMPD	#abs
    ----		1111110 00 1 CCCC 11 nnnnnnnnnnnnnnnn		JMPD	@rel
    
    ---- wr0	1111110 01 0 CCCC 00 nnnnnnnnnnnnnnnn		LINK	#abs			(jump, write {%00000000000000,Z,C,P} to $000)
    ---- wr0	1111110 01 0 CCCC 01 nnnnnnnnnnnnnnnn		LINK	@rel
    ---- wr0	1111110 01 0 CCCC 10 nnnnnnnnnnnnnnnn		LINKD	#abs
    ---- wr0	1111110 01 0 CCCC 11 nnnnnnnnnnnnnnnn		LINKD	@rel
    
    ----		1111110 01 1 CCCC 00 nnnnnnnnnnnnnnnn		CALL	#abs
    ----		1111110 01 1 CCCC 01 nnnnnnnnnnnnnnnn		CALL	@rel
    ----		1111110 01 1 CCCC 10 nnnnnnnnnnnnnnnn		CALLD	#abs
    ----		1111110 01 1 CCCC 11 nnnnnnnnnnnnnnnn		CALLD	@rel
    
    ----		1111110 10 0 CCCC 00 nnnnnnnnnnnnnnnn		CALLA	#abs
    ----		1111110 10 0 CCCC 01 nnnnnnnnnnnnnnnn		CALLA	@rel
    ----		1111110 10 0 CCCC 10 nnnnnnnnnnnnnnnn		CALLAD	#abs
    ----		1111110 10 0 CCCC 11 nnnnnnnnnnnnnnnn		CALLAD	@rel
    
    ----		1111110 10 1 CCCC 00 nnnnnnnnnnnnnnnn		CALLB	#abs
    ----		1111110 10 1 CCCC 01 nnnnnnnnnnnnnnnn		CALLB	@rel
    ----		1111110 10 1 CCCC 10 nnnnnnnnnnnnnnnn		CALLBD	#abs
    ----		1111110 10 1 CCCC 11 nnnnnnnnnnnnnnnn		CALLBD	@rel
    
    ----		1111110 11 0 CCCC 00 nnnnnnnnnnnnnnnn		CALLX	#abs
    ----		1111110 11 0 CCCC 01 nnnnnnnnnnnnnnnn		CALLX	@rel
    ----		1111110 11 0 CCCC 10 nnnnnnnnnnnnnnnn		CALLXD	#abs
    ----		1111110 11 0 CCCC 11 nnnnnnnnnnnnnnnn		CALLXD	@rel
    
    ----		1111110 11 1 CCCC 00 nnnnnnnnnnnnnnnn		CALLY	#abs
    ----		1111110 11 1 CCCC 01 nnnnnnnnnnnnnnnn		CALLY	@rel
    ----		1111110 11 1 CCCC 10 nnnnnnnnnnnnnnnn		CALLYD	#abs
    ----		1111110 11 1 CCCC 11 nnnnnnnnnnnnnnnn		CALLYD	@rel
    
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000000		COGID	D			(waits for hub) (doesn't write D if WC)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000001		TASKID	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000010		LOCKNEW	D			(waits for hub)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000011		GETLFSR	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000100		GETCNT	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000101		GETCNTX	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000110		GETACAL	D			(waits for mac)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000000111		GETACAH	D			(waits for mac)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001000		GETACBL	D			(waits for mac)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001001		GETACBH	D			(waits for mac)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001010		GETPTRA	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001011		GETPTRB	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001100		GETPTRX	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001101		GETPTRY	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001110		SERINA	D			(waits for rx if single-task, loops if multi-task, releases if WC)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000001111		SERINB	D			(waits for rx if single-task, loops if multi-task, releases if WC)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010000		GETMULL	D			(waits for mul if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010001		GETMULH	D			(waits for mul if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010010		GETDIVQ	D			(waits for div if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010011		GETDIVR	D			(waits for div if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010100		GETSQRT	D			(waits for sqrt if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010101		GETQX	D			(waits for cordic if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010110		GETQY	D			(waits for cordic if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000010111		GETQZ	D			(waits for cordic if single-task, loops if multi-task)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011000		GETPHSA	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011001		GETPHZA	D			(clears phsa)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011010		GETCOSA	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011011		GETSINA	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011100		GETPHSB	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011101		GETPHZB	D			(clears phsb)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011110		GETCOSB	D
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000011111		GETSINB	D
    
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100000		PUSHZC	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100001		POPZC	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100010		SUBCNT	D			(subtracts D from CNT, then CNTX if same thread)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100011		GETPIX	D			(takes 3 clocks, needs 3 clocks in prior two stages, condition only gates writes)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100100		BINBCD	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100101		BCDBIN	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100110		BINGRY	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000100111		GRYBIN	D			(takes two clocks)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101000		ESWAP4	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101001		ESWAP8	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101010		SEUSSF	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101011		SEUSSR	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101100		SPLITB	D			(also MERGEN)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101101		MERGEB	D			(also SPLITN)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101110		SPLITW	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000101111		MERGEW	D
    
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110000		CHKDEC	D			(if decimal, makes nibble, c=1)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110001		CHKHEX	D			(if hexadecimal, makes nibble, c=1)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110010		CHKLET	D			(if letter/"_", makes uppercase, c=1)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110011		CHKSYM	D			(if letter/"_"/numeral, makes uppercase, c=1)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110100		INCD	D			(D += $200)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110101		DECD	D			(D -= $200)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110110		INCDS	D			(D += $201)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000110111		DECDS	D			(D -= $201)
    
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000111000		POPT0	D			(pops from task 0's 4-level stack)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000111001		POPT1	D			(pops from task 1's 4-level stack)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000111010		POPT2	D			(pops from task 2's 4-level stack)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000111011		POPT3	D			(pops from task 3's 4-level stack)
    
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000111100		POP	D			(pops from task's 4-level stack)
    ZCW-		1111111 ZC 0 CCCC DDDDDDDDD 000111101		<empty>	D
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000111110		INCPAT	D			(takes four clocks)
    ZCM-		1111111 ZC 0 CCCC DDDDDDDDD 000111111		DECPAT	D			(takes four clocks)
    
    --L-		1111111 00 L CCCC DDDDDDDDD 001iiiiii		REPD	D/#1..512,#1..64	(REPD $1FF,#1..64 = infinite repeat, can use REPD #i)
    
    --L-		1111111 00 L CCCC DDDDDDDDD 010000000		CLKSET	D/#			(waits for hub)
    --L-		1111111 00 L CCCC DDDDDDDDD 010000001		COGSTOP	D/#			(waits for hub)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010000010		LOCKSET	D/#			(waits for hub)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010000011		LOCKCLR	D/#			(waits for hub)
    --L-		1111111 00 L CCCC DDDDDDDDD 010000100		LOCKRET	D/#			(waits for hub)
    --L-		1111111 00 L CCCC DDDDDDDDD 010000101		RDWIDE	D/PTRA/PTRB		(waits for hub)
    --L-		1111111 00 L CCCC DDDDDDDDD 010000110		RDWIDEC	D/PTRA/PTRB		(waits for hub if dcache miss)
    --L-		1111111 00 L CCCC DDDDDDDDD 010000111		RDWIDEQ	D/PTRA/PTRB		(waits for hub, doesn't affect dcache address/valid, waits 3 extra clocks)
    
    ZCL-		1111111 ZC L CCCC DDDDDDDDD 010001000		GETP	D/#			(pin into !Z/C via WZ/WC)
    ZCL-		1111111 ZC L CCCC DDDDDDDDD 010001001		GETNP	D/#			(pin into Z/!C via WZ/WC)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010001010		SEROUTA	D/#			(waits for tx if single-task, loops if multi-task, releases if WC)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010001011		SEROUTB	D/#			(waits for tx if single-task, loops if multi-task, releases if WC)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010001100		CMPCNT	D/#			(subtracts D from CNT, then CNTX if same thread)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010001101		WAITPX	D/#			(waits for any edge, +CNT if WC)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010001110		WAITPR	D/#			(waits for pos edge, +CNT if WC)
    -CL-		1111111 0C L CCCC DDDDDDDDD 010001111		WAITPF	D/#			(waits for neg edge, +CNT if WC)
    
    --L- wrD	1111111 ZC L CCCC DDDDDDDDD 010010000		COGNEW	D/#			(waits for hub)
    --L- wrD	1111111 ZC L CCCC DDDDDDDDD 010010001		COGNEWX	D/#			(waits for hub)
    --L-		1111111 00 L CCCC DDDDDDDDD 010010010		SETXCH	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010010011		SETTASK	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010010100		SETRACE	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010010101		SARACCA	D/#			(waits for mac)
    --L-		1111111 00 L CCCC DDDDDDDDD 010010110		SARACCB	D/#			(waits for mac)
    --L-		1111111 00 L CCCC DDDDDDDDD 010010111		SARACCS	D/#			(waits for mac)
    
    --L-		1111111 00 L CCCC DDDDDDDDD 010011000		SETPTRA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011001		SETPTRB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011010		ADDPTRA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011011		ADDPTRB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011100		SUBPTRA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011101		SUBPTRB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011110		SETWIDE	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010011111		SETWIDZ	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 010100000		SETPTRX	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010100001		SETPTRY	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010100010		ADDPTRX	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010100011		ADDPTRY	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010100100		SUBPTRX	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010100101		SUBPTRY	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010100110		PASSCNT	D/#			(takes two clocks, loops if (CNT - D) msb set)
    --L-		1111111 00 L CCCC DDDDDDDDD 010100111		WAIT	D/#			(waits 1+ clocks, 0 same as 1)
    
    --L-		1111111 00 L CCCC DDDDDDDDD 010101000		OFFP	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101001		NOTP	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101010		CLRP	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101011		SETP	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101100		SETPC	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101101		SETPNC	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101110		SETPZ	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010101111		SETPNZ	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 010110000		DIV64D	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110001		SQRT32	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110010		QLOG	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110011		QEXP	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110100		SETQI	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110101		SETQZ	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110110		CFGDACS	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010110111		SETDACS	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 010111000		CFGDAC0	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111001		CFGDAC1	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111010		CFGDAC2	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111011		CFGDAC3	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111100		SETDAC0	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111101		SETDAC1	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111110		SETDAC2	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 010111111		SETDAC3	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011000000		SETCTRA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000001		SETWAVA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000010		SETFRQA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000011		SETPHSA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000100		ADDPHSA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000101		SUBPHSA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000110		SETVID	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011000111		SETVIDY	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011001000		SETCTRB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001001		SETWAVB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001010		SETFRQB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001011		SETPHSB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001100		ADDPHSB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001101		SUBPHSB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001110		SETVIDI	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011001111		SETVIDQ	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011010000		SETPIX	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010001		SETPIXZ	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010010		SETPIXU	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010011		SETPIXV	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010100		SETPIXA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010101		SETPIXR	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010110		SETPIXG	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011010111		SETPIXB	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011011000		SETPORA	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011011001		SETPORB	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011011010		SETPORC	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011011011		SETPORD	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011011100		RDWIDEA	D/#1..512
    --L-		1111111 00 L CCCC DDDDDDDDD 011011101		RDWIDEB	D/#1..512
    --L-		1111111 00 L CCCC DDDDDDDDD 011011110		WRWIDEA	D/#1..512
    --L-		1111111 00 L CCCC DDDDDDDDD 011011111		WRWIDEB	D/#1..512
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011100x00		TARGOFF	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011100001		TARG	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011100010		TARGP	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011100011		TARGN	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011100101		TARGX	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011100110		TARGPX	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011100111		TARGNX	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011101000		JMPT0	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011101001		JMPT1	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011101010		JMPT2	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011101011		JMPT3	D/#
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011101100		PUSHT0	D/#			(pushes into task 0's 4-level stack)
    --L-		1111111 00 L CCCC DDDDDDDDD 011101101		PUSHT1	D/#			(pushes into task 1's 4-level stack)
    --L-		1111111 00 L CCCC DDDDDDDDD 011101110		PUSHT2	D/#			(pushes into task 2's 4-level stack)
    --L-		1111111 00 L CCCC DDDDDDDDD 011101111		PUSHT3	D/#			(pushes into task 3's 4-level stack)
    
    --L-		1111111 00 L CCCC DDDDDDDDD 011110000		PUSH	D/#			(pushes into task's 4-level stack)
    --L-		1111111 ZC L CCCC DDDDDDDDD 011110001		SETZC	D/#
    --L-		1111111 00 L CCCC DDDDDDDDD 011110010		SETLFSR	D/#
    
    --R-		1111111 00 x CCCC DDDDDDDDD 100000000		LOCPTRA	D			(PTRA = {D[15:0],%00})	(D[31:30] into Z/C via WZ/WC for LOCPTRA..CALLYD D)
    --R-		1111111 00 x CCCC DDDDDDDDD 100000001		LOCPTRB	D			(PTRB = {D[15:0],%00})
    
    --R-		1111111 ZC x CCCC DDDDDDDDD 100000010		JMP	D
    --R-		1111111 ZC x CCCC DDDDDDDDD 100000011		JMPD	D
    
    --R- wr0	1111111 ZC x CCCC DDDDDDDDD 100000100		LINK	D			(jump, write {Z,C,%00000000000000,P} to $000)
    --R- wr0	1111111 ZC x CCCC DDDDDDDDD 100000101		LINKD	D
    
    --R-		1111111 ZC x CCCC DDDDDDDDD 100000110		CALL	D
    --R-		1111111 ZC x CCCC DDDDDDDDD 100000111		CALLD	D
    
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001000		CALLA	D
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001001		CALLAD	D
    
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001010		CALLB	D
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001011		CALLBD	D
    
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001100		CALLX	D
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001101		CALLXD	D
    
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001110		CALLY	D
    --R-		1111111 ZC x CCCC DDDDDDDDD 100001111		CALLYD	D
    
    --R-		1111111 00 x CCCC DDDDDDDDD 100010000		LODINDA	D
    --R-		1111111 00 x CCCC DDDDDDDDD 100010001		LODINDB	D
    
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000000		RETA
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000001		RETAD
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000010		RETB
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000011		RETBD
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000100		RETX
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000101		RETXD
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000110		RETY
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110000111		RETYD
    
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110001000		RET
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110001001		RETD
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110001010		POLCTRA				(ctra-rollover into !Z/C)
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110001011		POLCTRB				(ctra-rollover into !Z/C)
    
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110001100		POLVID				(vid-ready into !Z/C)
    ----		1111111 00 x CCCC xxxxxxxxx 110001101		CAPCTRA
    ----		1111111 00 x CCCC xxxxxxxxx 110001110		CAPCTRB
    ----		1111111 00 x CCCC xxxxxxxxx 110001111		CAPCTRS
    
    ----		1111111 00 x CCCC xxxxxxxxx 110010000		SETPIXW
    ----		1111111 00 x CCCC xxxxxxxxx 110010001		CLRACCA
    ----		1111111 00 x CCCC xxxxxxxxx 110010010		CLRACCB
    ----		1111111 00 x CCCC xxxxxxxxx 110010011		CLRACCS
    
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110010100		CHKPTRX
    ZC--		1111111 ZC x CCCC xxxxxxxxx 110010101		CHKPTRY
    ----		1111111 00 x CCCC xxxxxxxxx 110010110		SYNCTRA				(waits for ctra if single-task, loops if multi-task))
    ----		1111111 00 x CCCC xxxxxxxxx 110010111		SYNCTRB				(waits for ctrb if single-task, loops if multi-task))
    
    ----		1111111 00 x CCCC xxxxxxxxx 110011000		DCACHEX
    ----		1111111 00 x CCCC xxxxxxxxx 110011001		ICACHEX
    ----		1111111 00 x CCCC xxxxxxxxx 110011010		ICACHEP
    ----		1111111 00 x CCCC xxxxxxxxx 110011011		ICACHEN
    
    ----		1111111 00 x 0000 xxxxxxxxx 110011100		TLOCK
    ----		1111111 00 x 0000 xxxxxxxxx 110011101		TFREE
    ----		1111111 00 x 0000 xxxxxxxxx 110011110		LOADT3
    ----		1111111 00 x 0000 xxxxxxxxx 110011111		SAVET3
    
    ----		1111111 00 x 0000 xxxxxxxxx 110100x00		TARGOFF
    ----		1111111 00 x 0000 xxxxxxxxx 110100001		TARG
    ----		1111111 00 x 0000 xxxxxxxxx 110100010		TARGP
    ----		1111111 00 x 0000 xxxxxxxxx 110100011		TARGN
    ----		1111111 00 x 0000 xxxxxxxxx 110100101		TARGX
    ----		1111111 00 x 0000 xxxxxxxxx 110100110		TARGPX
    ----		1111111 00 x 0000 xxxxxxxxx 110100111		TARGNX
    
    ----		1111111 00 x 0000 xxxxxxxxx 110101000		PASSTXA
    ----		1111111 00 x 0000 xxxxxxxxx 110101001		PASSTXB
    
    ----		0000000 00 0 0000 000000000 000000000		NOP
    
    
    x = don't care, use 0
    ---------------------------------------------------------------------------------------------------------------------
    
    
    Z	effect
    ------------------------------------------------------------------------------------------
    0	<none>
    1	wz
    
    
    C	effect
    ------------------------------------------------------------------------------------------
    0	<none>
    1	wc
    
    
    L	DDDDDDDDD	destination operand
    ------------------------------------------------------------------------------------------
    0/na	DDDDDDDDD	register
    1	#DDDDDDDDD	immediate, zero-extended
    
    
    I	SSSSSSSSS	source operand
    ------------------------------------------------------------------------------------------
    0/na	SSSSSSSSS	register
    1	#SSSSSSSSS	immediate, zero-extended
    
    
    CCCC	condition	(easier-to-read list)
    ------------------------------------------------------------------------------------------
    0000	never		1111	if_always	(default)
    0001	nc  &  nz	1100	if_c				if_b	if_x1
    0010	nc  &  z	0011	if_nc				if_ae	if_x0
    0011	nc		1010	if_z				if_e	if_1x
    0100	 c  &  nz	0101	if_nz				if_ne	if_0x
    0101	nz		1000	if_c_and_z	if_z_and_c		if_11
    0110	 c  <> z	0100	if_c_and_nz	if_nz_and_c		if_01
    0111	nc  |  nz	0010	if_nc_and_z	if_z_and_nc		if_10
    1000	 c  &  z	0001	if_nc_and_nz	if_nz_and_nc	if_a	if_00
    1001	 c  =  z	1110	if_c_or_z	if_z_or_c	if_be	if_not_00
    1010	 z		1101	if_c_or_nz	if_nz_or_c		if_not_10
    1011	nc  |  z	1011	if_nc_or_z	if_z_or_nc		if_not_01
    1100	 c		0111	if_nc_or_nz	if_nz_or_nc		if_not_11
    1101	 c  |  nz	1001	if_c_eq_z	if_z_eq_c		if_same
    1110	 c  |  z	0110	if_c_ne_z	if_z_ne_c		if_diff
    1111	always		0000	if_never
    
    
    CCCC	inda/indb - CCCC=1111 after stage 2 of pipeline if inda/indb used (indx=inda/indb)
    ------------------------------------------------------------------------------------------
    xx00	source indx
    xx01	source indx++
    xx10	source indx--
    xx11	source ++indx
    
    00xx	destination indx
    01xx	destination indx++
    10xx	destination indx--
    11xx	destination ++indx
    


    There are actually 12 other instructions which are aliases of certain cases of the main instructions:

    SWITCH
    SWITCHD

    MERGEN D/#
    SPLITN D/#

    PUSHA D/#
    PUSHB D/#
    PUSHX D/#
    PUSHY D/#

    POPA D/#
    POPB D/#
    POPX D/#
    POPY D/#

    You can imagine what they are, but these will be getting documented, too.

    This, Heater, brings the total instruction count to 459.
  • RaymanRayman Posts: 14,755
    edited 2014-03-20 07:39
    I'm feeling like maybe I need a DE2... Can someone please remind me: How much HUB RAM do you get with DE0 and DE2?
    I seem to recall that DE0 was something like 32kB, but I don't remember what DE2 gives you...
    cgracey wrote: »
    I'm compiling the DE0-Nano now. I had to remove the PIX, CORDIC, CTRB, SERB, and waveform output from CTRA to get things to fit. If this compile works, I'll try putting the waveform output back in for CTRA. Anyway, you need the VID and XFR blocks to do multithreaded VGA w/SDRAM, and those blocks are both in the DE0-Nano compile. For the SDRAM writing/reading, you'll need to be single-tasking because that requires exact timing.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 07:41
    Chip,

    Unless I am missing something, a dual-op instruction can be recovered:
    REPS    #n,#i    - execute 1..64 instructions 1..65536 times,   requires 1 spacer instruction
    REPD    #n,#i    - execute 1..64 instructions 1..512 times,     requires 3 spacer instructions
    
    instructions (iiiiii = #i-1, n_nnnn_nnnnnnnnn_nnn/nnnnnnnnn = #n-1)                            clocks
    

    REPD #n,#i seems to be an exact subset of REPS #n,#i - if I am correct, that frees up a double argument instruction.
  • potatoheadpotatohead Posts: 10,261
    edited 2014-03-20 07:50
    On the last image, we got 128K. I can't load this one until this evening, but the DE2 can do 256K RAM, so it's likely the answer Rayman is "all of it"
  • ctwardellctwardell Posts: 1,716
    edited 2014-03-20 07:58
    Chip,

    Unless I am missing something, a dual-op instruction can be recovered:
    REPS    #n,#i    - execute 1..64 instructions 1..65536 times,   requires 1 spacer instruction
    REPD    #n,#i    - execute 1..64 instructions 1..512 times,     requires 3 spacer instructions
    
    instructions (iiiiii = #i-1, n_nnnn_nnnnnnnnn_nnn/nnnnnnnnn = #n-1)                            clocks
    

    REPD #n,#i seems to be an exact subset of REPS #n,#i - if I am correct, that frees up a double argument instruction.


    It isn't really a true subset:

    Prop2_Docs.txt from 26Jan14, starting at line 1200:

    REPS differs from REPD by executing at the 2nd stage of the pipeline, instead of the 4th. By
    executing two stages earlier, it needs only one spacer instruction *. Because of its earliness,
    no conditional execution is possible, so it is forced to always execute, allowing the CCCC bits
    to be repurposed, affording a contiguous 16-bit constant for the repeat count.

    C.W.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 08:12
    Functionality is the same, so the only difference I can see is needing two extra spacers, which I was aware of when I posted it.

    That is not an advantage as far as I am concerned... so it is a candidate for the chopping block.
    ctwardell wrote: »
    It isn't really a true subset:

    Prop2_Docs.txt from 26Jan14, starting at line 1200:

    REPS differs from REPD by executing at the 2nd stage of the pipeline, instead of the 4th. By
    executing two stages earlier, it needs only one spacer instruction *. Because of its earliness,
    no conditional execution is possible, so it is forced to always execute, allowing the CCCC bits
    to be repurposed, affording a contiguous 16-bit constant for the repeat count.

    C.W.
  • ctwardellctwardell Posts: 1,716
    edited 2014-03-20 08:29
    Functionality is the same, so the only difference I can see is needing two extra spacers, which I was aware of when I posted it.

    That is not an advantage as far as I am concerned... so it is a candidate for the chopping block.

    Removing REPD would not free up a complete dual operand instruction.

    It shares opcode space with a lot of other instructions that start with "1111111 00" and then use part or all of S as an additional part of determining the actual instruction.

    C.W.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-20 08:41
    Maybe Bill is suggesting removing the REPS codepoint. The drawback is that we would need three filler instructions instead of one, and REPD #D,#S does not allow for as many iterations as REPS. The processor could recognize an unconditional REPD #D,#S instruction at stage 2 and treat it like REPS. REPD could also be treated as unconditional at all times to gain 4 more bits for the iteration count. Personally, I prefer separate REPD and REPS instructions.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 08:55
    No, I am suggesting removing REPD #i,#n as it offers no advantage over REPS #i,#n

    Seriously, what is the need for the REPD #i,#n variant, that does exactly the same thing, and requires two extra spacers?

    Can anyone think of a single usage case where REPD #i,#n is needed (and REPS #i,#n cannot be used)?

    I am not being snarky, I really am curious to see if I am missing a good usage case.

    Ok, the freed slot would be limited to a dual op instruction that does not need to be able to specify WC WZ
    Dave Hein wrote: »
    Maybe Bill is suggesting removing the REPS codepoint. The drawback is that we would need three filler instructions instead of one, and REPD #D,#S does not allow for as many iterations as REPS. The processor could recognize an unconditional REPD #D,#S instruction at stage 2 and treat it like REPS. REPD could also be treated as unconditional at all times to gain 4 more bits for the iteration count. Personally, I prefer separate REPD and REPS instructions.
  • ctwardellctwardell Posts: 1,716
    edited 2014-03-20 09:02
    Ok, the freed slot would be limited to a dual op instruction that does not need to be able to specify WC WZ

    The freed slot would also need the top 3 bits of S to be 001.

    I'm not opposed to removing REPD, just pointing out it doesn't gain a full dual opcode instruction.

    If a better use for the slot comes up then we have the option of letting it go.

    C.W.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-20 09:15
    Bill, if you get rid of REPD you lose the ability to set a variable loop count in a register. Having a variable loop size many not be as useful, but there could be cases where you would want to conditionally include extra code within the loop. This would require a way to avoid executing the extra code when the REPD completes, but that could be done with a conditional jump.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 09:15
    Thanks C.W., I *WAS* missing something ... the 001 as the top 3 bits of S!

    It is still potentially useful for a full D, partial S (0..63) alternate instruction, if needed.
    ctwardell wrote: »
    The freed slot would also need the top 3 bits of S to be 001.

    I'm not opposed to removing REPD, just pointing out it doesn't gain a full dual opcode instruction.

    If a better use for the slot comes up then we have the option of letting it go.

    C.W.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 09:16
    David,

    I only want to get rid of the

    REPD #i,#n ' constant loop count

    variant, and keep the other register based variant, which I agree is extremely useful.
    Dave Hein wrote: »
    Bill, if you get rid of REPD you lose the ability to set a variable loop count in a register. Having a variable loop size many not be as useful, but there could be cases where you would want to conditionally include extra code within the loop. This would require a way to avoid executing the extra code when the REPD completes, but that could be done with a conditional jump.
  • jazzedjazzed Posts: 11,803
    edited 2014-03-20 09:27
    Hi Chip.

    Thanks for the latest bundle!

    Heater. wrote: »
    2) Making PASM code universally usable across all languages as binary blobs no matter if it was written in a Spin object or in GAS or whatever. Does Spin wrap address that ?

    No. And there will never be a universally accepted solution for this. Use what's available.
  • ctwardellctwardell Posts: 1,716
    edited 2014-03-20 09:35
    It is still potentially useful for a full D, partial S (0..63) alternate instruction, if needed.

    Agreed. And like you said, only give up the immediate version.

    C.W.
  • dMajodMajo Posts: 855
    edited 2014-03-20 10:21
    Heater. wrote: »
    Invent-O-Doc

    From time to time I do have a "perfect idea" but I cannot see one on that page regarding the Spin compiler.

    But whilst we are at it, my thing there was all about how text processing instructions should not be polluting the instruction set space.

    UCASE being a non-starter because it cannot reliably uppercase the character set of the user, think
  • Heater.Heater. Posts: 21,230
    edited 2014-03-20 10:54
    dMajo,
    This is only because the PropTool was born "too simple".
    You have hit the nail on the head.

    Almost...It's not the PropTool that was born to simple it was the Spin language itself. Spin + included PASM that is.

    The structure of which you speak, "spin in one side and pasm in other having a fixed interface" is not a function of the tool used for editing but the very language definition. Don't forget there are many other Spin compilers that do not depend on any GUI tool to use.

    Aside: I have noticed many times that users of IDE's, and especially VB, cannot tell the difference between a programming language and the tool they use to edit it.

    Now, about those rules or structure...

    I think that to get Spin programmers to create PASM code that is usable outside of Spin, with C say, would require only slight modification to the Spin language.

    1) Introduce a PASM section. This is basically a DAT section with some extra rules...

    2) Make it a requirement that any PASM code to be launched into a COG has to be in a PASM section.

    3) Code on a PASM section cannot access any variables defined in Spin VAR blocks or DAT sections by name. This removes dependency of PASM from Spin data layout.

    4) Spin code cannot access any locations in a PASM section, at least by name. This prevents initializing of LONGs and such prior to loading to COG. Data that C would not know about.

    5) Due to 4) all parameters passed to PASM prior to launch are to go through pointers passed in PAR.

    6) All communication between a running PASM code and Spin go through shared HUB as normal, using pointers passed through PAR.

    With this in place there is no symbolic linkage between PASM and Spin, except for the starting address which Spin needs. With no linkage the resulting code can be compiled buy tools such as openspin, or BST into a binary blob that is usable by any language.

    However, I suspect the Spin community would hate this idea.
  • Heater.Heater. Posts: 21,230
    edited 2014-03-20 11:10
    dMajo,
    Perhaps you even don't need a publicly accessible obex. It can be an integration (repository) of the multi-platform IDE, it will be nice if it can have the possibility to keep in sync with a local copy (in the case internet is not available in the place of development). Publication of new objects will be trough the IDE when on-line.
    Ouch!, no, the OBEX has to be a publicly accessible resource. That's a wonderful thing.


    I personally think the whole thing should be moved to github but that's another story.


    But yes, I think being able to explore OBEX and pull down objects dropping them straight into your project (or local library) in an IDE is a great idea.
  • pedwardpedward Posts: 1,642
    edited 2014-03-20 11:13
    cgracey wrote: »
    Yes.

    I'm compiling the DE0-Nano now. I had to remove the PIX, CORDIC, CTRB, SERB, and waveform output from CTRA to get things to fit. If this compile works, I'll try putting the waveform output back in for CTRA. Anyway, you need the VID and XFR blocks to do multithreaded VGA w/SDRAM, and those blocks are both in the DE0-Nano compile. For the SDRAM writing/reading, you'll need to be single-tasking because that requires exact timing.

    Why can't you just give us a slower DE0-nano instead of redacting so much functionality? I'd be happy with a 40-60Mhz DE0 if it meant a full implementation of the core.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 11:20
    Very similar to Heater's proposal to above, but slightly simpler and thus more likely to be adapted

    From the latest docs:
    COGNEW D, S/#
    COGINIT D, S/#, #0..7

    For COGNEW, D specifies a long address in hub memory that is the start of the program that is to be
    loaded into the idle cog, while S is a 18-bit parameter (usually an address) that will be conveyed to
    the PTRA's of that cog.

    The PTRB's of that cog will be set to the start address of its new program in
    hub memory, which is the same as the D value used in the COGNEW instruction, AND'd with $3FFFC to
    form a hub long address.

    AUGS could be used to point to the parameter block with #.

    The problem is that D is a register - a cog register - which pretty much requires the cog image to be patched. Except....

    I think what we need to do is:
           LOCPTRA  #hubaddress_of_parameters
           LOCPTRB  #hubaddress_of_program
           COGNEW  ptrb,ptra
    

    If SPIN is disallowed from accessing labels inside the programs code, then binary objects can be written that will work the same with Spin and C.

    Spin & C can set up initial data in the parameter section, just like Spin currently does in the cog image - but this time, as the cog image is not modified, the same blob would work fine with C or SPIN.

    Note the above does not care if the cog will be running in cog or hubexec mode!

    A binary driver would just have to publish the definition of its parameter block, the start of which would have to be long aligned.

    This also means that we can free up two dual-reg opcodes, and use argumentless opcodes for COGNEW and COGINIT ... forcing the PTRA/PTRB usage using LOCPTR. Unless I am mistaken, this will actually require less logic to implement than the current COGNEW/COGINIT!
  • Heater.Heater. Posts: 21,230
    edited 2014-03-20 11:30
    Bill,

    How is your a different proposal?.
    If SPIN is disallowed from accessing labels inside the programs code, then binary objects can be written that will work the same with Spin and C.
    I don't see how you do that without introducing something like a PASM section into the language. After all Spin does need DAT for other purposes some times.

    Doesn't the linkage have to be broken both ways? Code in a PASM section should not know about where named Spin variables are.
  • potatoheadpotatohead Posts: 10,261
    edited 2014-03-20 11:33
    What?? SPIN needs to be able to access the labels like it does now!

    Breaking SPIN to make it some sort of feeder to C is a crock of you know what I'm tempted to write here.

    Frankly, if SPIN gets "fixed" in that way, some of us will "unfix" it. Just know that.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-20 11:38
    I've modified PASM programs to work with C by moving all of the variables that are initialized by Spin code to the beginning of the PASM code. The first line of the PASM code just jumps over the variables. This allows C to set up PASM variables just like Spin does. As an example, here are the first few lines of a VGA driver written in PASM.
                            org     0
    
    initialization          jmp     #skipover
    
    directionState          long    0
    videoState              long    0
    frequencyState          long    0
    numTileLines            long    0
    numTileVert             long    0
    visibleScale            long    0
    invisibleScale          long    0
    horizontalLongs         long    0
    tilePtr1                long    0
    tileMap1                long    0
    pixelColorsAddress      long    0
    syncIndicatorAddress    long    0
    
    
    skipover
                            mov     vcfg, videoState          ' Setup video hardware.
                            mov     frqa, frequencyState
                            movi    ctra, #%0_00001_101
    
    The C startup routine looks like this
    #include <stdint.h>
    #include "propeller.h"
    
    #define bitsPerPixel      1
    #define horizontalScaling 1
    #define horizontalPixels  640
    #define NUM_TILES 256
    
    extern int8_t vga_array[];
    
    typedef struct VgaVarS {
        uint32_t directionState;
        uint32_t videoState;
        uint32_t frequencyState;
        uint32_t verticalScaling;
        uint32_t verticalPixels;
        uint32_t visibleScale;
        uint32_t invisibleScale;
        uint32_t horizontalLongs;
        uint32_t *colortable1;
        uint32_t *buffer1;
        uint32_t *pixelColorsAddress;
        uint32_t *syncIndicatorAddress;
    } VgaVarT;
    
    void VgaStart(int pinGroup, int verticalResolution, int *newDisplayPointer,
    int *colortable, int *pixelColors, int *syncIndicator)
    {
        int i, temp;
        VgaVarT vga;
        int frequencyState;
    
        vga.directionState = 0xff << (8 * pinGroup);
        vga.videoState = 0x200000ff | (pinGroup << 9) | (bitsPerPixel << 28);
        temp = (25175000 + 1600) / 4;
        frequencyState = 1;
        for (i = 0; i < 32; i++)
        {
            temp <<= 1;
            frequencyState <<= 1;
            if (i == 31) frequencyState++;
            if (temp >= CLKFREQ)
            {
                temp -= CLKFREQ;
                frequencyState++;
            }
        }
        vga.frequencyState = frequencyState;
        vga.verticalScaling = 480 / verticalResolution;
        vga.verticalPixels = 480 / vga.verticalScaling;
        vga.visibleScale = (horizontalScaling << 12) + ((640 * 32) >> bitsPerPixel) / horizontalPixels;
        vga.invisibleScale = ((8 << bitsPerPixel) << 12) + 160;
        vga.horizontalLongs = horizontalPixels / (32 >> bitsPerPixel);
        vga.buffer1 = newDisplayPointer;
        vga.colortable1 = colortable;
        vga.pixelColorsAddress = pixelColors;
        vga.syncIndicatorAddress = syncIndicator;
    
        memcpy(vga_array + 4, &vga, sizeof(VgaVarT));
    
        cognew(vga_array, 0);
    }
    
    Using this method, both C and Spin can use the same PASM code.
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-03-20 11:49
    Currently, with the boot loader and PNUT and there not being SPIN in ROM, we are writing and loading pure PASM that has essentially decoupled from Spin. With a few changes, lose the CON section and replace with "label EQU value" and remove the DAT, the code is pure PASM looking like almost any other ASM. Your PASM2 code no longer needs to have a one line Spin program wrapping it doing a COGINIT/COGNEW. The bootloader takes care of that. (Yay!)

    We are creating loadable blobs. Earlier, someone (sorry, forgot who) suggested removing the zero fill from the front of the binary to make it a more relocatable blob.

    When OpenSpin gets the Spin2/PASM2 spec or even with Pnut, how much harder would it to finish the decoupling? Put in a $PASM_STRICT directive to give you PASM decoupled from SPIN. You the PASM programmer are responsible for properly using whatever you expect passed in the PAR register. Your variable namespace is the simple PASM namespace of offsets from ORG or ORGH. If you do not specify $PASM_STRICT, you get the wonderfully blended marriage of Spin and PASM that everyone has grown up with.
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 11:49
    I started by saying it is very similar :-)

    But there are some differences.
    Heater. wrote: »
    Bill,

    How is your a different proposal?.

    - your version did not address hubexec code

    - mine does not directly state your (3), I assumed it - my bad - due to defining these binary modules to be independent of anything external, except the parameter block

    - I am proposing modifying COGINIT/COGNEW, simplifying them, by using LOCPTRA & LOCPTRB, instead of D&S, for the code pointer and parameter pointer (this frees two full dual op codes)

    - not modifying the instructions for LOCPTRA/LOCPTRB gives some issues for specifying D

    - explicit LOCPTRA/B loading should remove some logic from COGINIT/COGNEW

    So it is mostly the same (very similar), except for explicit LOCPTRA/LOCPTRB, simplifying COGINIT/NEW logic, and eliminates the D issue

    Basically, it is additional suggestions to your proposal :)
    Heater. wrote: »
    I don't see how you do that without introducing something like a PASM section into the language. After all Spin does need DAT for other purposes some times.

    Doesn't the linkage have to be broken both ways? Code in a PASM section should not know about where named Spin variables are.

    I was expecting to re-purpose ORG / ORGH for the start of such a block, but we could have "PASM" or "DRIVER" or "MODULE" keyword for that.

    Absolutely, the linkage has to be broken both ways, limited to just the Parameter block - which is public.

    The whole idea was to totally decouple drivers from the language... be it Spin, C, Forth etc.
  • potatoheadpotatohead Posts: 10,261
    edited 2014-03-20 11:53
    That seems a much better call. And making PASM BLOBS makes more sense now with all the cool options.

    Don't we already have a directive that avoids the zero fill? It has been a while since that discussion, but I recall something like:

    ORGH $1000

    --some data---

    ORGH $2000
    ORG 0

    --a cog image--

    etc...

    Did we not do that?
  • Bill HenningBill Henning Posts: 6,445
    edited 2014-03-20 11:55
    potatohead,

    I am curious.

    Why is it a problem for Spin to modify the variables in the parameter section (PTRA) instead of inside the body of the driver code?

    By having a separate parameter section, pointed to by PTRA, we can use the neat PTRA indexed modes to read/write the parameters from the driver.

    It makes the driver interfacing so much cleaner.

    I am very open to examples of why this would be bad / inferior.
    potatohead wrote: »
    What?? SPIN needs to be able to access the labels like it does now!

    Breaking SPIN to make it some sort of feeder to C is a crock of you know what I'm tempted to write here.

    Frankly, if SPIN gets "fixed" in that way, some of us will "unfix" it. Just know that.
  • potatoheadpotatohead Posts: 10,261
    edited 2014-03-20 12:00
    Re: SPIN and PASM should not know where variables are.

    No. That tight marriage, particularly with inline PASM needs to be there. If somebody isn't interested in interoperating with other languages, having SPIN behave as it does right now is a huge benefit. I am opposed to breaking that for everyone.

    Offering an option, such as STRICT, or INTEROP makes sense, because those who are interested get help making sure that all happens.

    Right now, SPIN + PASM is seriously powerful precisely because those limits aren't there.

    @Bill: One case is inline. With common labels, inline can work extremely lean. One can quite literally, type the block, using the same names, variables, addresses, the works. Doing this is super easy, and for people wanting to use some PASM, it is a no brainer to enter in just the bit they want to use and continue on. Originally, the snippet idea was to handle that case, but now that we have HUBEX, we can now just do it inline, quickly, easily.

    Reuse is a great reason to author things intended for general consumption. We all benefit from the effort and I'm for ways to help people do that when doing so is their intent.

    But reuse is not always the primary case, which is exactly why SPIN should do what it does now.

    Think about UNIX. Some command line tools are written in the classic reuse way. They can be piped, redirected, whatever. Others are written to get stuff done, and they may not work in those classic ways.

    Would we break UNIX just to insure that anything people authored would be usable no matter what?

    No, of course not. What we did do is make it easier to do that, but we didn't lock people into having to do that.

    Same case here.

    Let's get SPIN and PASM out the door as the flexible, powerful thing it is. Then we can add on and assist people with common sense options to address the "needs to work with C" use cases. Building it in takes away from the "who cares?" use case, and making people have to care is a sure fire way to insure they really don't. Ever.
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-03-20 12:10
    Sapieha wrote: »
    Hi Chip.

    I have one question?

    Can't PNut cut filling 0000000 in bin file to first ORGH position --->
    That will give simpler make separately loaded modules.

    It was this post about the zero fill that I couldn't remember. ORGH may not fill the gaps with zero but the front end appears to be filler. If you don't zero fill though in all places when you create the binary, then the boot loader (or blob loader) needs to have the smarts to load pieces in places which means you needs to have headers inside the binary to tell it the next blob is so long and loads at this absolute hub address, no? If you do zero fill, then a binary is truly a binary image of what should be loaded from address 0 to the last address.
Sign In or Register to comment.