Jump to content
  • entries
    335
  • comments
    900
  • views
    258,593

self-modifying code HELP!


EricBall

492 views

My Propeller video driver is almost done, but I've run into a snag. The following is a snippet from the pixel byte to long lookup routine.

 

				SHR	 sprgfx1, #8		  ' shift byte into position
			MOV	 sprbyte, sprgfx1
			AND	 sprbyte, #$0FF  wz
			MOVS	:byte6, sprbyte		  ' update source pointer
			MOVD	:byte6, sprdata		  ' update destination pointer
			ADD	 sprdata, #1
:byte6  IF_NZ   MOV	 sprdata, sprbyte		  ' copy color lookup table entry to lineRAM
			SHR	 sprgfx1, #8	 wz
			MOVS	:byte7, sprgfx1
			MOVD	:byte7, sprdata
:byte7  IF_NZ   MOV	 sprdata, sprbyte		  ' won't work due to pipeline
			DJNZ	count2, #:nxtspr		  ' decrement active sprite counter
			JMP	 #doblank		  ' max number of active sprites reached
:nxtspr		 ADD	 sprptr, #4
			DJNZ	count1, #:loop		  ' 48+16+223 = 287 (288) max cycles / sprite
doblank

What's going on here is some self-modifying code 'cause the Propeller doesn't have any indirect addressing. My problem is the propeller is moderately pipelined, so the next instruction is fetched before the current instruction has been executed. So :byte7 MOV won't reflect the MOVD as it currently stands. For all of the other cases I've been able to slip the ADD instruction back before the MOV, but I don't have that option for :byte7. I could just put a NOP in there, but that adds 4 cycles to the loop, which effectively adds 16 cycles due to external memory timing. (ick!) Other options:

 

1. Slide back the DJNZ. But then I need to copy :byte7 so it gets executed before the JMP. That's 3 opcodes (again due to the pipeline) and I'd like to only add max 2 for other reasons.

2. Roll up the byte to long translation. Code space efficient, but more cycles.

 

Any other suggestions?

 

 

(The wz / IF_NZ are to make color 0 transparent. The condition codes are under application control and every instruction may be optionally executed. So wz sets/clears the Zero condition code and IF_NZ executes the MOV only if the Zero condition code is cleared, i.e. the value of sprbyte is non-zero.)

3 Comments


Recommended Comments

Can't the SHR be moved like so?

 

:byte6  IF_NZ   MOV	 sprdata, sprbyte		  ' copy color lookup table entry to lineRAM
			MOVS	:byte7, sprgfx1
			MOVD	:byte7, sprdata
			SHR	 sprgfx1, #8	 wz
:byte7  IF_NZ   MOV	 sprdata, sprbyte		  ' won't work due to pipeline

 

Or does the flag state get pipelined too?

 

Nope the SHR changes sprgfx1 which is then used by MOVS.

Link to comment

Of course!!

 

Not enough coffee today...

 

I'm looking at the last set of code you sent my way. Maybe there is something that can go in there that will save cycles later..

Link to comment

Figured out how to do it in 2 opcodes and 0 extra cycles for the main loop!

 

:byte6  IF_NZ		   MOV	 sprdata, sprbyte
					SHR	 spraddr, #8	 WZ
					MOVS	:byte7, spraddr
					MOVD	:byte7, sprdata
					DJNZ	count2, #:byte7
					MOV	 :byte7b, :byte7
					JMP	 #:byte7b
:byte7  IF_NZ		   MOV	 sprdata, sprbyte
:nxtspr				 ADD	 sprptr, #4
					DJNZ	count1, #:loop  WZ	  ' 48+16+223 = 287 (288) max cycles / sprite
:byte7b IF_NZ		   MOV	 sprdata, sprbyte

 

The neat bit is the DJNZ count1 sets the WZ flag when it falls through, which then means the :byte7b instruction gets NOP'd.

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...