It is currently Mon Dec 11, 2017 4:14 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Mon Jul 24, 2017 2:14 am 
Offline
User avatar

Joined: Fri Jul 21, 2017 4:38 am
Posts: 31
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:
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:


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 2:24 am 
Offline
User avatar

Joined: Sun Dec 12, 2010 10:27 pm
Posts: 297
Location: Hong Kong
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.


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 2:25 am 
Offline
User avatar

Joined: Fri Jul 21, 2017 4:38 am
Posts: 31
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 :)


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 2:38 am 
Offline
User avatar

Joined: Thu Sep 15, 2016 6:29 am
Posts: 446
Location: Denmark (PAL)
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.


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 2:44 am 
Offline
User avatar

Joined: Fri Jul 21, 2017 4:38 am
Posts: 31
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:
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



Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 3:13 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1116
Location: Gothenburg, Sweden
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.

_________________
http://www.frankengraphics.com - personal NES blog


Last edited by FrankenGraphics on Mon Jul 24, 2017 3:19 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 3:15 am 
Offline
User avatar

Joined: Fri Jul 21, 2017 4:38 am
Posts: 31
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:)


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 3:21 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1116
Location: Gothenburg, Sweden
Edited my post right when you posted your reply - it now includes a comment on macros

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 3:27 am 
Offline
User avatar

Joined: Fri Jul 21, 2017 4:38 am
Posts: 31
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 :)


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 3:36 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1116
Location: Gothenburg, Sweden
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

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 5:15 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19322
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 8:39 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5886
Location: Canada
4 increments is the break-even point for transferring X to A and using ADC:
Code:
   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.


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 9:24 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10164
Location: Rio de Janeiro - Brazil
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:
  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.


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 9:30 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1116
Location: Gothenburg, Sweden
That's really neat, tokumaru!

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Mon Jul 24, 2017 9:43 am 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
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: kkfos.aspekt.fi


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 34 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group