Jump to content
IGNORED

MOVI@


artrag

Recommended Posts

I'm very rusty with the CP1600 asm, and I have a silly question. There is something stupid I'm doing and I cannot find.

This routine is called with R0 aiming to an address in the video table and R2 aiming to a 4 word array 

I need to print a 2x2 block from R0 using the 4 word aimed by R2

I was trying to use the auto increment feature in MVI@ and MVO@

What is wrong in this code ?

 

PRINT2X2: PROC	
		MOVR R0,R4
		MOVR R5,R3
		MOVR R2,R5

		MVI@ R5,R1
		MVO@ R1,R4	

		MVI@ R5,R1
		MVO@ R1,R4	

        ADDI #18,R4

		MVI@ R5,R1
		MVO@ R1,R4	

		MVI@ R5,R1
		MVO@ R1,R4	

		MOVR R4,R0
		MOVR R3,R5
		JR R5
		ENDP

 

Link to comment
Share on other sites

3 minutes ago, Arnauld said:

This code looks correct. What's going wrong? Note that you may want to save back the final value of R5 in R2 for consecutive calls (if that makes any sense) and you can just do JR R3 instead of MOVR R3,R5 / JR R5.

Do you mean in R3 ? I.e. like this

PRINT2X2: PROC	
		MOVR R0,R4
		MOVR R5,R3
		MOVR R2,R5

		MVI@ R5,R1
		MVO@ R1,R4	

		MVI@ R5,R1
		MVO@ R1,R4	

		ADDI #18,R4

		MVI@ R5,R1
		MVO@ R1,R4	

		MVI@ R5,R1
		MVO@ R1,R4	

		MOVR R4,R0
		JR R3
		ENDP

 

Edited by artrag
Link to comment
Share on other sites

33 minutes ago, artrag said:

Do you mean in R3 ? I.e. like this


PRINT2X2: PROC	
		MOVR R0,R4
		MOVR R5,R3
		MOVR R2,R5

		MVI@ R5,R1
		MVO@ R1,R4	

		MVI@ R5,R1
		MVO@ R1,R4	

		ADDI #18,R4

		MVI@ R5,R1
		MVO@ R1,R4	

		MVI@ R5,R1
		MVO@ R1,R4	

		MOVR R4,R0
		JR R3
		ENDP

 

Yes.  You are not required to return with the same register.  So if your return address was saved in R3, just JR from it like you have above.


Pro Tip:

For the record, R5 is merely a convention for return addresses.  The only constraint is that the JSR instruction (Jump To Subroutine, which saves the return address then jumps) accepts only either R5 or R4 as the placeholder for the return value, but at some early time R5 was established as the de facto standard for the return address.
 

Once the jump is made, there is nothing special about R5 (except that it holds the return address, of course).  Returning from the subroutine is done with the JR (Jump To Register) which has no register restrictions, and is not even subroutine-specific.

 

29 minutes ago, artrag said:

Solved! The issue was outside this code, in the value of R2 

Thanks!

Great!


By the way, one thing to consider:  MOVR and INCR both cost 6 CPU cycles, so copying a register in order to do a single auto-increment indirect copy results in a wash.  Plus it has the downside of consuming R5 or R4.  


For example:

	MOVR R0,R4  ' 6 cycles
	MOVR R5,R3  ' <-- incidental cost of 6 cycles to save R5 contents
	MOVR R2,R5  ' 6 cycles

	MVI@ R5,R1  ' \_ copies & increments both R5 and R4
	MVO@ R1,R4  ' /   Saves 6 cycles for INCR per register

	MVI@ R5,R1  ' \_ copies and imcrements again
	MVO@ R1,R4	' /   Saves 6 cycles *if* you intend to use the final addresses again


As illustrated, if you only increment R4 once, the 6 cycles you save from avoiding an INCR instruction are spent in copying the original value onto R4.

 

Of course, there may be other reasons why you copy the original arguments, so this is just intended as a helpful general observation.

 

   dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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...