6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 1:55 pm

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Mon Mar 27, 2006 11:00 pm 
Offline

Joined: Mon Mar 27, 2006 10:54 pm
Posts: 13
Location: Sydney
Hi,

I'm relatively new to 6502 assembly, but since I built a Replica-1 (Apple-1 clone) in January, I've been doing quite a lot. What I need to do at the moment, is to transform a byte of the form "XXXY YYZZ" to "001Z ZXXX", and various similar operations. Now I can obviously do this with various rotates and SEC,CLCs, but it seems to me that there are probably some nice tricks that enable this to be done more elegantly. My primary interest is saving space, since this is part of some code that I want to squeeze into my ROMs - and it's gettin pretty tight! :)

I was hoping for some advice.

Thanks

Ken


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Mar 27, 2006 11:22 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Here is my solution:
Code:
     ; value loaded in A
     LDX  #$04
     STX  temp        ; any zp location
     ROL  A
     ROL  temp
     ROL  A
     ROL  temp
     ROL  A
     ROL  temp
     AND  #$18
     ORA  temp
     ; result in temp


Hope that helps.

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Mar 27, 2006 11:47 pm 
Offline

Joined: Mon Mar 27, 2006 10:54 pm
Posts: 13
Location: Sydney
Thanks very much - that does help. I think you mean result in A though.

Ken


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Mar 27, 2006 11:52 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Nope, the result will be in temp. If you want result in A, add "LDA temp" to the code.

For other bit manipulations, you just need to figure out the least amount of shifts needed to accomplish your goal. Also, store differnt intermediate values in several zp locations can help save code length.


Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 12:07 am 
Offline

Joined: Mon Mar 27, 2006 10:54 pm
Posts: 13
Location: Sydney
Hmmm, sorry if I'm misunderstanding something (as I said, I'm fairly new to 6502 assembly), but your last two instructions - the AND and ORA won't change temp, only A. So if the result is in temp, you could stop earlier!

I understand what you're doing. You put 00000100 in temp, and then copy the last 3 bits accross via the carry to get 0010 0XXX. Then the AND makes A just 000Y Y000, and ORA with temp will make A 001Y YXXX - temp will be unchanged.

At any rate, I wasn't using a temp location, and that was making it harder and more verbose.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 12:15 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
OOps! You were right, the result is in A. I'm sorry for confusing the issue.
And your interpretation was 100% correct.

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 12:41 am 
Offline

Joined: Wed Oct 22, 2003 4:07 am
Posts: 51
Location: Norway
Unless I'm misunderstanding something, would'nt this be faster and smaller?
Code:
cmp #$80
rol a
cmp #$80
rol a
cmp #$80
rol a
and #$1f
ora #$20


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 1:02 am 
Offline

Joined: Mon Mar 27, 2006 10:54 pm
Posts: 13
Location: Sydney
Looks like it. :-)

This is a good way for me to learn I think. :-)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 1:34 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1748
Location: Sacramento, CA
Thowllly wrote:
Unless I'm misunderstanding something, would'nt this be faster and smaller?
Code:
cmp #$80
rol a
cmp #$80
rol a
cmp #$80
rol a
and #$1f
ora #$20


Great job. I've never imagined it that way... you learn something new everyday... thanks !!!

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 5:23 am 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
Thowllly wrote:
Unless I'm misunderstanding something, would'nt this be faster and smaller?
Code:
cmp #$80
rol a
cmp #$80
rol a
cmp #$80
rol a
and #$1f
ora #$20


How 'bout

Code:
cmp #$80
rol A
cmp #$80
rol A
asl A
and #$1F
adc #$20


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 28, 2006 6:05 am 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
bogax wrote:
Thowllly wrote:
Unless I'm misunderstanding something, would'nt this be faster and smaller?
Code:
cmp #$80
rol a
cmp #$80
rol a
cmp #$80
rol a
and #$1f
ora #$20


How 'bout

Code:
cmp #$80
rol A
cmp #$80
rol A
asl A
and #$1F
adc #$20



or this even (check me :) )

Code:
asl A
adc #$80
rol A
asl A
and #$1F
adc #$20


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Mar 29, 2006 7:04 am 
Offline

Joined: Tue Dec 30, 2003 10:35 am
Posts: 42
Most entertaining thread ever. I don't think I'll ever enjoy assembly programming on any other processor as much as on the 6502. What fun. Here's my analysis of the last solution posted (extra bit in comments is the carry bit):

Code:
; In           Out
; XXXY YYZZ -> 001Z ZXXX
; ABCD EFGH    001G HABC

            ; 0 ABCD EFGH
asl A       ; A BCDE FGH0
adc #$80    ; B ?CDE FGHA
rol A       ; ? CDEF GHAB
asl A       ; C DEFG HAB0
and #$1F    ; C 000G HAB0
adc #$20    ; 0 001G HABC


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Mar 29, 2006 7:10 am 
Offline

Joined: Wed Oct 22, 2003 4:07 am
Posts: 51
Location: Norway
After my first post I had a thought; the last ORA could also have been a EOR, and if A is loaded right before my code it can be shortened to:
Code:
lda $xx ;compare to 0 puts the first x in c, only inverted.

rol a
cmp #$80
rol a
cmp #$80
rol a
and #$1f
eor #$30 ;also invert the first x again


But with the last instruction tied up in both setting the 1 bit and inverting that x, I would never have thought of your idea
bogax wrote:
How 'bout

Code:
cmp #$80
rol A
cmp #$80
rol A
asl A
and #$1F
adc #$20
Thats very clever!

bogax wrote:
or this even (check me :) )

Code:
asl A
adc #$80
rol A
asl A
and #$1F
adc #$20
While this is just brilliant! :shock:


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Mar 29, 2006 10:53 am 
Offline

Joined: Mon Mar 27, 2006 10:54 pm
Posts: 13
Location: Sydney
blargg wrote:
Most entertaining thread ever. I don't think I'll ever enjoy assembly programming on any other processor as much as on the 6502. What fun.

I've certainly enjoyed it, and learnt a lot - which was of course the idea. I'm writing an assembler to use with my Apple-1 replica, and the problem comes from some changes I've made to the Apple 1 disassembler so it shares some of my assemblers routines and data to save space. My assembler is single pass, uses standard syntax, and allows symbols and simple expressions (but no macros). To be able to fit in ROM, the assembler, disassembler, and a small command shell have to fit into 3800 bytes. I've finished the coding now and am just testing and fixing bugs. I currently have 80 bytes to spare! :)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Mar 29, 2006 5:47 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
blargg wrote:
Code:
; In           Out
; XXXY YYZZ -> 001Z ZXXX
; ABCD EFGH    001G HABC

            ; 0 ABCD EFGH
asl A       ; A BCDE FGH0
adc #$80    ; B ?CDE FGHA
rol A       ; ? CDEF GHAB
asl A       ; C DEFG HAB0
and #$1F    ; C 000G HAB0
adc #$20    ; 0 001G HABC


Ahh, I see it now. It took several HOURS of staring at this to see it. :)


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 7 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:  
cron