6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 09, 2024 2:33 pm

All times are UTC




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Wed Nov 08, 2023 8:10 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
I'm sure this has been done before but it's a handy reminder that the carry is unaffected by logical instructions, increment, and decrement... this little routine takes an integer of any desired length (well, up to 256, but if you've got 2kbit integers, you're probably not using a 6502!) and negates it. X is a pointer to the integer on page zero; Y is the length of the integer in bytes.

Code:
negate:               ; negate a little-endian integer on zero page
                  ; x points to the lowest byte, y has size

   sec               ; first addition will add one
neg_1:
      lda 0,x
      eor #$ff      ; invert the byte
      adc #0         ; add one to the first, others depend on c flag
      sta 0,x         ; invert one byte
      inx
      dey   
      bne neg_1      ; and then the rest of them
   rts


A couple of signed arithmetic routines needed to change the sign of their operands before doing their sums; doing it this way saves a lot of space and doesn't take much longer than doing it inline.

Neil


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 08, 2023 9:50 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
I have visions of you doing maths on 256-byte-long integers.

I think you could use this instead of the EOR:

Code:
    lda #0
    sbc 0,x
    sta 0,x


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 09, 2023 6:49 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
Doh, yes of course I can. Which saves an extra byte, too as well as being a few clocks faster... that's from too much thinking in hardware terms... first chip inverts it, second chip adds it, with the carry handily set :D

Neil


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 09, 2023 8:45 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
If you'd switch to big endian values it could be even smoother:

Code:
negateBE:          ; negate a big-endian integer on zero page
                   ; x is the size

      sec          ; prepare for sbc
neg_1:
      lda #0
      sbc 0,x      ; subtract the value from 0
      sta 0,x      ; invert one byte
      dex
      bpl neg_1    ; and then the rest of them
      rts


Actually I guess that for long values the big endian mode is a better choice


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 09, 2023 9:00 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 683
Location: Potsdam, DE
Ah, but the problem is that I'm too old and set in my ways to believe that big endian could ever be better, even if it clearly is :mrgreen:


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2023 11:42 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
I think you can get little endian mode as good as big endian, if you use the rollover 'feature' of the zeropage addressing, if I'm not mistaken. Or even without that. Just use 'base-251' as address and count x from 251 up.

What do you think?

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 4:55 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8177
Location: Midwestern USA
fachat wrote:
I think you can get little endian mode as good as big endian, if you use the rollover 'feature' of the zeropage addressing, if I'm not mistaken. Or even without that. Just use 'base-251' as address and count x from 251 up.

What do you think?

Won’t work on the 65C816 in native mode.  :D

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 10:56 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
BigDumbDinosaur wrote:
fachat wrote:
I think you can get little endian mode as good as big endian, if you use the rollover 'feature' of the zeropage addressing, if I'm not mistaken. Or even without that. Just use 'base-251' as address and count x from 251 up.

What do you think?

Won’t work on the 65C816 in native mode.  :D


Agreed on zp. I'm too deep into 6502 still :)

But if values are anywhere in memory you could just use
Code:
    SEC
    LDX #252
l1  LDA #0
    SBC integeraddress-252,X
    STA integeraddress-252,X
    INX
    BNE l1

To invert a 32 bit / 4 byte value.

Right?

Edit: corrected off-by-one from 251 to 252

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Last edited by fachat on Sat Nov 11, 2023 7:26 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 12:35 pm 
Offline
User avatar

Joined: Sun Nov 01, 2020 10:36 am
Posts: 35
Location: Tatooine
For a 32bit/4 bytes value the index you are looking for is 252 (4 iterations: 252...255).
Anyway you're falling almost certainly in a situation where you're crossing the page boundary, so 1 cycle will be added in two of those instructions; in the end you're just sparing the 2 bytes of the CPX #val.


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 7:19 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
It's a just matter of optimization for code size vs speed. ;-)

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 7:28 pm 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 993
Location: near Heidelberg, Germany
BB8 wrote:
For a 32bit/4 bytes value the index you are looking for is 252 (4 iterations: 252...255).

Thanks for the hint. I edited the post to the correct value.

_________________
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/


Top
 Profile  
Reply with quote  
PostPosted: Sat Nov 11, 2023 8:32 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1928
Location: Sacramento, CA, USA
fachat wrote:
It's a just matter of optimization for code size vs speed. ;-)

Woz in 1976 would have done the same without the slightest hesitation.

_________________
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)


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

All times are UTC


Who is online

Users browsing this forum: Paganini and 9 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: