Is there a better way to INX 4 times?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

User avatar
mantanz
Posts: 31
Joined: Fri Jul 21, 2017 4:38 am

Is there a better way to INX 4 times?

Post by mantanz »

Hi guys,

Here's my code to move my spaceship up. Just wondering in there's 'cleaner' way to perform INX four times in a row? It works obviously but it just feels and looks wrong to me. LOL. I reralise I can nest another loop but that's a heap more code than just writing INX four times and I'm guessing less efficient? I really don't know when it comes to this stuff...

Code: Select all

ReadUp: 
	LDA $4016      
	AND #%00000001  
	BEQ ReadUpDone 
	LDX #$0000		
	.MoveUp:		
		LDA $0200, X 
		SEC             
		SBC #player_speed 
		STA $0200, X      
		INX			
		INX
		INX
		INX
		CPX #$18	
		BNE .MoveUp	
ReadUpDone:
User avatar
Gilbert
Posts: 564
Joined: Sun Dec 12, 2010 10:27 pm
Location: Hong Kong
Contact:

Re: Is there a better way to INX 4 times?

Post by Gilbert »

Didn't read the codes, but what's the problem with using INX four times? It looks clean (for assembly especially) and effective and probably uses fewer cycles than most other solutions(possibly more compact codes even, as the 4 INXs are just 4 bytes in machine code).
If you have to increase X by 40 then it's justified that it couldn't be a good idea to write INX 40 times, but for doing this only 4 times there isn't much reason to not do this.
User avatar
mantanz
Posts: 31
Joined: Fri Jul 21, 2017 4:38 am

Re: Is there a better way to INX 4 times?

Post by mantanz »

Gilbert wrote:Didn't read the codes, but what's the problem with using INX four times? It looks clean (for assembly especially) and effective and probably uses fewer cycles than most other solutions(possibly more compact codes even, as the 4 INXs are just 4 bytes in machine code).
If you have to increase X by 40 then it's justified that it couldn't be a good idea to write INX 40 times, but for doing this only 4 times there isn't much reason to not do this.
Okay, cool. I guess I just don't like repeating code but if that's the correct way to do it I'll leave it as is :)
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Is there a better way to INX 4 times?

Post by Sumez »

If the issue is with cleaning up the look of your code, rather than performance or size optimization, you could use macros instead. It usually helps keeping things much more manageable, without impacting the actual result.
User avatar
mantanz
Posts: 31
Joined: Fri Jul 21, 2017 4:38 am

Re: Is there a better way to INX 4 times?

Post by mantanz »

Sumez wrote:If the issue is with cleaning up the look of your code, rather than performance or size optimization, you could use macros instead. It usually helps keeping things much more manageable, without impacting the actual result.
Good point. That's what I'll do.

Right now I'm struggling with splitting my controller code out into another asm file... grrr....

EDIT: I have updated my code with this. Now it looks much nicer in all my controller handling stuff. Thanks! Now I know about macros! lol.

Code: Select all

four_count	.macro ;This saves writing INX four times in a row
			INX
			INX
			INX
			INX
			.endm

---------------------------------

; D-pad UP
ReadUp: 
	LDA $4016       ; player 1 D-pad up
	AND #%00000001  ; only look at bit 0
	BEQ ReadUpDone  ; branch to ReadADone if button is NOT pressed (0)
	; The following loops through and updates each sprite's Y position
	LDX #$0000		; counter for loop
	.MoveUp:		; local label
		LDA $0200, X       ; load X sprite Y position (sprite 0 Y pos is $0200, sprite 1 Y pos id $204 etc...)
		SEC             ; make sure carry flag is set
		SBC #player_speed       ; A = A - player_speed
		STA $0200, X       ; save X sprite Y position
		four_count
		CPX #$18	; check if if X hits number of sprites x 4 (in this case 24 (18 in hex))
		BNE .MoveUp	; if it hasn't, run through loop again
ReadUpDone:        ; handling this button is done

User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Is there a better way to INX 4 times?

Post by FrankenGraphics »

depending on your assembler, you can also use the .repeat / .rept directive to repeat a line or block of code at assembly time. So you don't really need to define a macro for it.

your macro looks odd.

nomally, a macro would be defined like this:

.macro name
do this and that
.endm

Put your macros in a separate file and .include / .inc it at the top of your main file.
you don't need a label.

pardon the absense of formatting. iOS text editor seems to throw a fit when a "sentence" begins with a dot and you're trying to mark it.
Last edited by FrankenGraphics on Mon Jul 24, 2017 3:19 am, edited 1 time in total.
User avatar
mantanz
Posts: 31
Joined: Fri Jul 21, 2017 4:38 am

Re: Is there a better way to INX 4 times?

Post by mantanz »

FrankenGraphics wrote:depending on your assembler, you can also use the .repeat / .rept directive to repeat a line or block of code at assembly time. So you don't really need to define a macro for it.
Cool! I'm using NESASM3. I'll look into that:)
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Is there a better way to INX 4 times?

Post by FrankenGraphics »

Edited my post right when you posted your reply - it now includes a comment on macros
User avatar
mantanz
Posts: 31
Joined: Fri Jul 21, 2017 4:38 am

Re: Is there a better way to INX 4 times?

Post by mantanz »

FrankenGraphics wrote:depending on your assembler, you can also use the .repeat / .rept directive to repeat a line or block of code at assembly time. So you don't really need to define a macro for it.

your macro looks odd.

nomally, a macro would be defined like this:

.macro name
do this and that
.endm

Put your macros in a separate file and .include / .inc it at the top of your main file.
you don't need a label.

pardon the absense of formatting. iOS text editor seems to throw a fit when a "sentence" begins with a dot and you're trying to mark it.
Hehe I just looked up macros in NESASM and copied how it was done on whatever the page was I found. Works but I'll reformat it :)
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Is there a better way to INX 4 times?

Post by FrankenGraphics »

Oh, in that case - i just checked and NESASM 3 is apparently agnostic if you do it like:

label .macro

or

.macro name

you might to want to do it like the latter because that'd work in several assemblers.

for reference, here it is: http://www.nespowerpak.com/nesasm/usage.txt
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Is there a better way to INX 4 times?

Post by tepples »

If you're writing NES-specific code, such as sprite drawing code, you can use the unofficial instruction AXS to subtract an arbitrary amount from the X register.

I recommend unofficial instructions only for code that interacts with a particular piece of hardware, not platform-independent game logic such as collision detection, because they will not work on a port of your game to a 65C02 or 65816 platform, such as Atari Lynx, TurboGrafx-16, or Super NES.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Is there a better way to INX 4 times?

Post by rainwarrior »

4 increments is the break-even point for transferring X to A and using ADC:

Code: Select all

	INX     ; 2 cycles, 1 byte
	INX
	INX
	INX
	; total:  8 cycles, 4 bytes

	TAX     ; 2 cycles, 1 byte
	CLC     ; 2 cycles, 1 byte
	ADC #4  ; 2 cycles, 2 bytes
	TXA     ; 2 cycles, 1 byte
	; total:  8 cycles, 5 bytes
If you could guarantee that carry is clear, the CLC could be omitted and then the ADC version would be 2 cycles faster.

If also you need to preserve the current value in A then the break-even point could be as high as 7 increments.

If your value isn't in X to begin with then it's also different (A doesn't have increment, and INC directly on memory is much slower than INX). This page is really good quick reference for instruction timings: http://www.obelisk.me.uk/6502/reference.html


A pile of 4 INXs in a row is pretty normal 6502 code.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Is there a better way to INX 4 times?

Post by tokumaru »

I usually reserve a page of ROM for values $00-$ff, so if I wanted I could do the following to increment X by 4:

Code: Select all

  lda ByteTable+4, x
  tax
This is a little faster than INX x4 (6 cycles vs. 8) while also occupying 4 bytes, but I definitely wouldn't use 256 bytes of ROM just for this. This table has many other uses though, such as simulating TXY ("ldy ByteTable, x") and TYX ("ldx ByteTable, y") instructions, in addition to the quick increments/decrements by constant numbers to index registers.

Many would consider this table a waste of space, but it has already made it possible for me to avoid temporary variables and also write slightly faster code in loops (thus saving a significant amount of cycles), by making the index registers more capable than usual.
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Is there a better way to INX 4 times?

Post by FrankenGraphics »

That's really neat, tokumaru!
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Is there a better way to INX 4 times?

Post by thefox »

tokumaru wrote:I usually reserve a page of ROM for values $00-$ff, so if I wanted I could do the following to increment X by 4:
(Just make sure to pad the table with 4 more values 0..3, because that "4+X" doesn't wrap when > 255.)
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Post Reply