It is currently Mon Dec 17, 2018 4:37 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: Is this code okay?
PostPosted: Wed Oct 18, 2006 5:18 pm 
Offline

Joined: Sat Oct 14, 2006 4:10 am
Posts: 15
I've been messing around with the 6502 simulator and tried making a program that counts up from $00 to $1F and stores the numbers in memory in as few steps as possible. Could this code be made shorter somehow?

Code:
   .ORG $8000
   LDA #$20
   sta $8088
   LDX #$00   
loop:   
   TXA
   CMP $8088
   beq end
   sta $8040,x
   INX
   jmp loop
end:   


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 18, 2006 6:15 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3601
Location: Indianapolis
Code:
.org $8000

 ldx #0
loop:
 txa
 sta $8040,x
 inx
 cpx #$20
 bne loop


Originally 20 bytes, now 11 bytes.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 18, 2006 7:59 pm 
Offline

Joined: Wed Mar 22, 2006 8:00 am
Posts: 354
If you use zero page memory and count down from $1F to $00, you can make the code even shorter:

Code:
  LDX #$1F
loop:
  TXA
  STA <$40, X
  DEX
  BPL loop


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 18, 2006 10:25 pm 
Offline

Joined: Sat Oct 14, 2006 4:10 am
Posts: 15
thanks memblers... I forgot about cpx. :roll: I was hoping to make it so you could dynamically change the value of the counter from within the program though. Can it be made shorter if that was a consideration?

(btw it's just a brain excersize)

thanks too dvdmth. I thought about that but I wanted it to be able to store the numbers anywhere in memory.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 1:31 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
It's still shorter (two bytes) and faster (2 clocks per iteration) to count down than up, due to DEX doing an implicit CMP #0 after decrementing X. Replace <$40 with $8040 and you have the same result as your code. Note that this will only work for counting down from $80 or less, since greater values would cause the loop to terminate after the first iteration.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 2:34 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7604
Location: Chexbres, VD, Switzerland
To count up to number greather than $80, you'll have to trick a bit :
Code:
     ldx #$ff
-    txa
     sta Somewhere,X
     dex
     bne -
     stx Somewhere

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 12:21 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3601
Location: Indianapolis
If you wanted to be evil, you could do self-modifying code in RAM (going from dvdmth's code).

Code:
loop_value = label+1
 lda #$40-1 ;(do 64)
 sta loop_value

.org somewhere_in_RAM
label:
  LDX #$1F
loop:
  TXA
  STA <$40, X
  DEX
  BPL loop


Or the easier way, put an RTS at the end and do an LDX then JSR to the loop label. But JSR/RTS together costs something like 12 cycles, JMP is only 3, so the self-modifying code is good if speed really counts.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 1:15 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11013
Location: Rio de Janeiro - Brazil
Easy guys, or you'll confuse the poor guy. This battle for speed/size is eventually important, but for now, as long as the code does what it's supposed to, it's OK.

Oxymoron, it doesn't really matter if there is a better/shorter way to do some task when you're learning 6502 assembly. Because, you know, there always is a faster way to do things. What is important now is that you understand how each instruction behaves and affects the CPU, and that you can successfully code a program that will do what you expect it to.

I say that because sometimes, when you look at clever, tight code, it isn't always clear what it's supposed to do, 'cause often there are "tricks" involved. And learning through tricks is not a good way to start.

In the future, when you start thinking the same way as the processor works, these kind of improvemnts/shortcuts will also start to appear clearly in your head. Don't worry about that too much right now.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 1:33 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7604
Location: Chexbres, VD, Switzerland
Quote:
This battle for speed/size is eventually important, but for now, as long as the code does what it's supposed to, it's OK.

Well, it's important in up to a certain point, but Memblers tend to be a bit too "evil" usually, and well, my opinion is that you should always with code that is understandable and easily modifiable/fixable, even if you do a minimun of tricks to gain ROM space.
If you really need trick, it is recommanded to comment them very well and/or to have a commented "untricked" version of the code in order to have yourself understand what you was doing when you look at code you wrote 6 months ago.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 4:13 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3601
Location: Indianapolis
Well he did say it was just a brain exercise, rather than some project code. So I figure anything goes, I didn't post my fastest methods though since the goal was size. :) Just some (partially or fully) unrolled loops anyways.

But I definitely agree though that code should be kept easy to read and understand. Except inside of loops that run several times per frame, then you definitely should use little tricks like the one dvdmth posted wherever possible. Ditching that compare when copying 32 bytes saves 64 cpu cycles (over half a scanline), the 2 less ROM bytes only matter if you're writing a 1024 byte game or something. :)

Also nothing wrong with writing code that works, then coming back later and optimizing if needed. Like when I first wrote Roadkill (while still learning how to code), most of the frame was taken up by hit detection code. When I optimized it some years later, the results were the same but the code was something like 300% faster. When handling 62 sprites, that's a tremendously, ridiculously huge difference.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 7:40 pm 
Offline

Joined: Sat Oct 14, 2006 4:10 am
Posts: 15
I appreciate the tips guys. I don't know what the < in "<$40" means? But otherwise those examples mostly make sense. Although like I said, I didn't want to make the code do something different (ie count down instead of up, although I didn't think about DEX setting the Z flag - is that what you mean when you say "implicit CMP #0" blargg?) or make it incporporate "tricks", I just wanted to know if I had missed something obvious that would have reduced the number of steps. I can't even think of a reason to actually use this routine off the top of my head, I had just written a bunch of things in the simulator and decided to try cutting them down to make them as small as possible as an excersize.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 8:17 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20887
Location: NE Indiana, USA (NTSC)
oxymoron wrote:
I appreciate the tips guys. I don't know what the < in "<$40" means?

In 65xx assembly language, < means bits 7-0, > means bits 15-8 ("page"), and | means bits 23-16 ("bank", generally 65816 only). If you know C, I can explain a lot of 65xx concepts in terms of C.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 8:33 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11013
Location: Rio de Janeiro - Brazil
He probably did that to make sure that the instruction would be assembled to the zero-page addressing version (where the high byte of the address is implied, $00). Otherwise, it could be assembled to the equivalent of "STA $0040, X", which would be wasteful (both in space and time) in this case. I wouldn't usually do that, and assume that the assembler is smart enough to use the appropriate instruction.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 9:43 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3601
Location: Indianapolis
NESASM is the only assembler I'm aware of that requires you to force it to use zero-page. Actually though when making my NSF player I ran across a few games that never use zero-page, always stuff like STA $0000 (whoops!).

But for a practical example of using < and >, you'll very often see stuff like this:

Code:
filething = $C032

 lda #>filething ; $C0
 sta addr_hi
 lda #<filething ; $32
 sta addr_lo


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 20, 2006 8:43 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7604
Location: Chexbres, VD, Switzerland
WLA-DX almost forces you to either default to zero page and force to non-zero page or the other way arround (like NESASM does).

In NESASM (and ONLY in NESASM) :
Quote:
lda <Label

means like
Code:
lda Label.b

would in WLA-DX

In WLA-DX it is use to just say
Code:
lda Label

for zero page and to have
Code:
lda Label.w

for non-zero page instruction.
This is isn't all that bad because it forces the programmer to know wich varaiables aren't in zero page, and you can use "sta $2000" without mention "sta $2000.w", so it is just for variables and not for registers you have to do the .w trick.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: pubby and 3 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