Shop OBEX P1 Docs P2 Docs Learn Events
Block read/write on next silicon — Parallax Forums

Block read/write on next silicon

cgraceycgracey Posts: 14,133
edited 2019-06-04 19:31 in Propeller 2
I made some late changes to the PTRA/PTRB circuits to sensibly accommodate block reads and writes, but I accidentally oversimplified things.

On the next silicon, when doing a 'SETQ{2} + RDLONG/WRLONG/WMLONG PTRx' sequence to read or write a block of longs, no random index will be allowed.

Only 5 PTRx options will be recognized by the silicon:
	SETQ	#100-1		'read 100 longs @PTRA into regs 0..99
	RDLONG	0,PTRA

	SETQ	#100-1		'read 100 longs @PTRA+400 into regs 0..99, PTRA += 400
	RDLONG	0,++PTRA

	SETQ	#100-1		'read 100 longs @PTRA-400 into regs 0..99, PTRA -= 400
	RDLONG	0,--PTRA

	SETQ	#100-1		'read 100 longs @PTRA into regs 0..99, PTRA += 400
	RDLONG	0,PTRA++

	SETQ	#100-1		'read 100 longs @PTRA into regs 0..99, PTRA -= 400
	RDLONG	0,PTRA--

In other words, the index becomes the (SETQ value + 1) << 2 for PTRx-modifying instances and $00000 for non-PTRx-modifying instances.

I realized this as I was going over the interpreter code, making sure it would easily be compatible with the next silicon. In several cases, I will need to use an extra instruction to modify PTRA now.

What used to be something like this:
	setq	#6-1		'push z/pbase/vbase/dbase/y/x (include x to init 'result' in hub)
	wrlong	z,ptra++[5]	'ptra points to 'result' afterwards

Will now need to be coded like this:
	setq	#6-1		'push z/pbase/vbase/dbase/y/x (include x to init 'result' in hub)
	wrlong	z,ptra++
	sub	ptra,#1<<2	'ptra points to 'result' afterwards

The point of the change was to make things like block moves easy:
	rep	#4,#64		'move 64KB quickly from @ptra to @ptrb
	setq	#$100-1		'read 1KB into registers $000..$0FF
	rdlong	0,ptra++
	setq	#$100-1		'write 1KB from registers $000..$0FF
	wrlong	0,ptrb++

I should have keyed this block behavior from distal index values, perhaps, but it is this simplistic way now.

Comments

  • TonyB_TonyB_ Posts: 2,125
    edited 2019-06-04 20:24
    cgracey wrote: »
    What used to be something like this:
    	setq	#6-1		'push z/pbase/vbase/dbase/y/x (include x to init 'result' in hub)
    	wrlong	z,ptra++[5]	'ptra points to 'result' afterwards
    

    Will now need to be coded like this:
    	setq	#6-1		'push z/pbase/vbase/dbase/y/x (include x to init 'result' in hub)
    	wrlong	z,ptra++
    	sub	ptra,#1<<2	'ptra points to 'result' afterwards
    

    My head is now full of bricks, lintels and other building components, but I think a problem at one time was ptrx not being modified at all after block moves. Pointing to the "next" location rather than the previous "end" location appears to be all right, although losing the index is unfortunate perhaps.

    In the "used to be" code, were data written to ptra, ptra+4, ..., ptra+5*4, then ptra := ptra+5*4? If so, that was rather odd and not what the code suggested.
  • cgraceycgracey Posts: 14,133
    TonyB_, the idea in the 'used to be code' was that PTRA would wind up pointing at 'x' in the hub, while 'x' is the top of the stack and maintained in the cog at all times, not just the hub. This way, instruction like NOT only work on 'x', without the need to pop and push.
  • Cluso99Cluso99 Posts: 18,069
    My head hurts :(

    Using xxPTRA or PTRAxx will use the address (PTRA + SETQ * 4) as the first address ?

    And the final result of PTRA will be +(SETQ+1)*4 ?

    Example
    SETQ     #($20-1)     ‘ $19
    WRLONG  cog, PTR++.   ‘ hubadd =  PTRA + $20*4 onwards
     and the final value of PTRA = PTRA + $20*4 (ie the next address)
    

    So we have to initially set
    PTRA = hubadr - (value of SETQ*4. ie $20*4)

  • cgraceycgracey Posts: 14,133
    edited 2019-06-04 23:20
    Cluso99 wrote: »
    My head hurts :(

    Using xxPTRA or PTRAxx will use the address (PTRA + SETQ * 4) as the first address ?

    And the final result of PTRA will be +(SETQ+1)*4 ?

    Example
    SETQ     #($20-1)     ‘ $19
    WRLONG  cog, PTR++.   ‘ hubadd =  PTRA + $20*4 onwards
     and the final value of PTRA = PTRA + $20*4 (ie the next address)
    

    So we have to initially set
    PTRA = hubadr - (value of SETQ*4. ie $20*4)

    For 'SETQ + RDLONG PTRA':

    PTRA means use PTRA, PTRA stays the same
    PTRA++ means use PTRA and post-update PTRA to PTRA+(SETQ +1)*4
    PTRA-- means use PTRA and post-update PTRA to PTRA-(SETQ +1)*4
    ++PTRA means use PTRA+(SETQ +1)*4 and post-update PTRA to PTRA+(SETQ +1)*4
    --PTRA means use PTRA-(SETQ +1)*4 and post-update PTRA to PTRA-(SETQ +1)*4

    Just think of these sequences as giant pushes and pops, where {++/--}PTRx{++/--} is updated with the block size times 4 (for longs).

    For {++/--}PTRx{++/--}, the assembler makes the 5-bit offset value either +1 or -1. The MSB of the offset value gets used to determine add or subtract.
  • If you are planning to "fix" this behavior, how will you distinguish between hardware revs, from a compiler/runtime perspective? Will the same code run on r1 and r2+ versions of silicon?
  • cgraceycgracey Posts: 14,133
    pedward wrote: »
    If you are planning to "fix" this behavior, how will you distinguish between hardware revs, from a compiler/runtime perspective? Will the same code run on r1 and r2+ versions of silicon?

    It's not going to change. It's done. Hopefully, there are no bugs. I would have done it differently, had I been aware of the implications, but it's pretty straightforward: Don't use [index] with SETQ+RDLOAD, as it will adjust PTRx automatically. Of course, this behavior is different than the first-rev silicon.

    Actually, you can write SETQ+RDLONG+PTRx code that will function on both chips, but be limited to a small adjustment range.
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-06-05 03:29
    cgracey wrote: »
    Cluso99 wrote: »
    My head hurts :(

    Using xxPTRA or PTRAxx will use the address (PTRA + SETQ * 4) as the first address ?

    And the final result of PTRA will be +(SETQ+1)*4 ?

    Example
    SETQ     #($20-1)     ‘ $19
    WRLONG  cog, PTR++.   ‘ hubadd =  PTRA + $20*4 onwards
     and the final value of PTRA = PTRA + $20*4 (ie the next address)
    

    So we have to initially set
    PTRA = hubadr - (value of SETQ*4. ie $20*4)

    For 'SETQ + RDLONG PTRA':

    PTRA means use PTRA, PTRA stays the same
    PTRA++ means use PTRA and post-update PTRA to PTRA+(SETQ +1)*4
    PTRA-- means use PTRA and post-update PTRA to PTRA-(SETQ +1)*4
    ++PTRA means use PTRA+(SETQ +1)*4 and post-update PTRA to PTRA+(SETQ +1)*4
    --PTRA means use PTRA-(SETQ +1)*4 and post-update PTRA to PTRA-(SETQ +1)*4

    Just think of these sequences as giant pushes and pops, where {++/--}PTRx{++/--} is updated with the block size times 4 (for longs).

    For {++/--}PTRx{++/--}, the assembler makes the 5-bit offset value either +1 or -1. The MSB of the offset value gets used to determine add or subtract.

    Thanks Chip.

    So this line in your post
    	SETQ	#100-1		'read 100 longs @PTRA+400 into regs 0..99, PTRA += 400
    	RDLONG	0,++PTRA
    
    should be
    	SETQ	#100-1		'read 100 longs from @PTRA  into regs 0..99, PTRA += 400
    	RDLONG	0,++PTRA
    
    ie this "@PTRA+400" was the confusing part.

    I presume BYTE and WORD work similarly? (ie *2 and *1) - used of course without SETQ.
  • cgraceycgracey Posts: 14,133
    Cluso99 wrote: »
    cgracey wrote: »
    Cluso99 wrote: »
    My head hurts :(

    Using xxPTRA or PTRAxx will use the address (PTRA + SETQ * 4) as the first address ?

    And the final result of PTRA will be +(SETQ+1)*4 ?

    Example
    SETQ     #($20-1)     ‘ $19
    WRLONG  cog, PTR++.   ‘ hubadd =  PTRA + $20*4 onwards
     and the final value of PTRA = PTRA + $20*4 (ie the next address)
    

    So we have to initially set
    PTRA = hubadr - (value of SETQ*4. ie $20*4)

    For 'SETQ + RDLONG PTRA':

    PTRA means use PTRA, PTRA stays the same
    PTRA++ means use PTRA and post-update PTRA to PTRA+(SETQ +1)*4
    PTRA-- means use PTRA and post-update PTRA to PTRA-(SETQ +1)*4
    ++PTRA means use PTRA+(SETQ +1)*4 and post-update PTRA to PTRA+(SETQ +1)*4
    --PTRA means use PTRA-(SETQ +1)*4 and post-update PTRA to PTRA-(SETQ +1)*4

    Just think of these sequences as giant pushes and pops, where {++/--}PTRx{++/--} is updated with the block size times 4 (for longs).

    For {++/--}PTRx{++/--}, the assembler makes the 5-bit offset value either +1 or -1. The MSB of the offset value gets used to determine add or subtract.

    Thanks Chip.

    So this line in your post
    	SETQ	#100-1		'read 100 longs @PTRA+400 into regs 0..99, PTRA += 400
    	RDLONG	0,++PTRA
    
    should be
    	SETQ	#100-1		'read 100 longs from @PTRA  into regs 0..99, PTRA += 400
    	RDLONG	0,++PTRA
    
    ie this "@PTRA+400" was the confusing part.

    I presume BYTE and WORD work similarly? (ie *2 and *1)

    No. The ++PTRx means pre-add the index before using, while PTRx++ means post-add the index after using.
  • Cluso99Cluso99 Posts: 18,069
    edited 2019-06-05 03:42
    Chip,
    Getting my head around this...

    Read/write block... Added "PTRA not updated".
    	SETQ	#100-1		'read 100 longs @PTRA into regs 0..99, PTRA not updated
    	RDLONG	0,PTRA
    
    Got it :smile:

    Block move... Added "ptra += $100*4 (ie next address)"
    	rep	#4,#64		'move 64KB quickly from @ptra to @ptrb
    	setq	#$100-1		'read 1KB into registers $000..$0FF
    	rdlong	0,ptra++        ' ptra += $100*4 (ie next address)
    	setq	#$100-1		'write 1KB from registers $000..$0FF
    	wrlong	0,ptrb++        ' ptra += $100*4 (ie next address)
    
    Got it :smile:

    Push[n] onto stack... Added "ptra += $100*4 (ie next address)"
    	setq	#6-1		'push z/pbase/vbase/dbase/y/x (include x to init 'result' in hub)
    	wrlong	z,ptra++        ' ptra += $6*4 (ie next address)
    	sub	ptra,#1<<2	'ptra points to 'result' afterwards
    
    This is what I would expect the behaviour to be!
    ie ptra would be incremented by the number of bytes/words/longs written/read.
    In reality, this is equivalent to (for concept only - will not work due to pipeline!)
            rep    #2,5             'push z/pbase/vbase/dbase/y/x (include x to init 'result' in hub)
            wrlong  z,ptra++        ' ptra += 1*4 (ie next address) each time thru
            add     $-1,x512        ' inc z in prev instruction
    
    To do it the way you intended, IMHO would be a bug, and many would get caught out.
Sign In or Register to comment.