6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 3:15 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Sign extension question
PostPosted: Sat Apr 29, 2006 12:16 pm 
Offline

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

I need to add a signed 8 bit number (in zero page location TEMP1) to a stored 16 bit number (in zero page locations LVALL,H). Below is my current method. I was wondering if anyone had any suggestions or improvements.
Code:
ADD16X   
   LDX #$00
   LDA TEMP1   ; signed 8 bit number
   CMP #$00
   BPL .CONT
   DEX      ; bit 7 was set, so it's a negative
.CONT   STX TEMP2
   CLC   
   ADC LVALL
   STA LVALL   ; update the stored number low byte
   LDA LVALH
   ADC TEMP2
   STA LVALH   ; update the stored number high byte
   RTS   

Thanks,

Ken


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Apr 29, 2006 2:37 pm 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
This should work ..

Code:
ADD16X
   LDA   TEMP1      ; signed 8 bit number
   BPL   .CONT      ; skip high byte decrement if +ve

   DEC   LVALH      ; number is -ve so decrement stored number high byte
.CONT
   CLC            ; clear carry for add
   ADC   LVALL      ; add to 16 bit low byte
   STA   LVALL      ; update the stored number low byte
   BCC   .EXIT      ; exit if no carry

   INC   LVALH      ; add the carry to the stored number high byte
.EXIT
   RTS

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Apr 30, 2006 1:36 am 
Offline

Joined: Mon Mar 27, 2006 10:54 pm
Posts: 13
Location: Sydney
Nice - thanks. Not only short and clear, but also avoids using X, so you've saved me quite a few bytes there.

Ken


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon May 01, 2006 4:33 pm 
Offline

Joined: Sun Aug 24, 2003 7:17 pm
Posts: 111
I would say that the task simply is not appropriately formulated in the first place!

If the two byte value should be the sum of many one byte "signed" values you should consider it as a signed value too. If you for some reason know from the start that the sum is positive you kind of miss the most significant bit, i.e. you only have 15 bits fo the end sum. But what do you otherwise do if some "partial sum" should be negative? With absolutely standard signed arithmetic you then have
Code:
     CLC
     LDA TEMP1
     ADC LVALL
     STA LVALL
     LDA #00
     ADC LVALH
     STA LVALH
     BVS ERROR
     RTS

If now the final sum in LVALL,LVALH stays positive at all times, fine! If not, also fine!

This is the straight-forward approach in the spirit of the chip design! Rock solid! No "tricks" needed!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon May 01, 2006 4:46 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Mats wrote:
I would say that the task simply is not appropriately formulated in the first place!


Strange; I understood the problem as written perfectly.

Quote:
Code:
     CLC
     LDA TEMP1
     ADC LVALL
     STA LVALL
     LDA #00
     ADC LVALH
     STA LVALH
     BVS ERROR
     RTS

If now the final sum in LVALL,LVALH stays positive at all times, fine! If not, also fine! This is the straight-forward approach in the spirit of the chip design! Rock solid! No "tricks" needed!


The poster of the question is adding a signed 8-bit value to a signed 16-bit quantity. This mandates that the 8-bit value be sign-extended first. The code above works if and only if the signed value is guaranteed to be positive at all times.

I'm not a fan of unnecessary tricks except where performance counts (see my thread on arithmetic shifts). I would start off by writing this instead:

Code:
  clc
  lda TEMP1
  bmi isNeg
  adc LVALL
  sta LVALL
  lda #0
  adc LVALH
  sta LVALH
back:
  ...etc...

isNeg:
  adc LVALL
  sta LVALL
  lda #$FF
  adc LVALH
  sta LVALH
  jmp back


That would be my initial solution. It takes more memory, and MAY even take more time to execute, but it'll work. Then, from there, I'd optimize as required.

update -- I did a preliminary timing analysis of my code versus lee's with the assumption that everything is stored in zero-page, and it looks like mine is only 3 cycles slower than his in the case of a negative number. Not bad at all, I'd say.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon May 01, 2006 10:31 pm 
Offline

Joined: Sun Aug 24, 2003 7:17 pm
Posts: 111
You are perfectly right. But "basically" I think I was right that the straightforward way to do this absolutely standard task is to

Step 1:

Extend the signed one byte variable to a build a signed 2 byte variable by "prolonging" the sign bit, i.e. (for example)

80 => FF80
7F => 007F

Then do 2 byte signed arithmetic!

This is exactly what you (correctly) did! I wrote my thing a bit to quickly! Sorry for that!

This could also be seen as 8 "ASR" (division by 256) of 8000 and 7F00 , respectively, where "ASR" would be the non-existing operation "Arithmetic Shift Right" copying the value of the sign bit to the second most significant bit, i.e division with 2


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

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Mats wrote:
You are perfectly right. But "basically" I think I was right that the straightforward way to do this absolutely standard task is to


Yes -- provided performance or tight memory size isn't an issue. Lee's approach is 'straight forward' in the sense that it exploits the logic of 2's compliment math, but it does require a bit of algebra to see how it works.

The "trick" is that, should you have a negative number N, you can break it up such that N = $FF00 + N', where N' is between $80 and $FF inclusive.

Thus, LVAL + $FF00 + N' is what's being computed, and since addition is commutative, and since $FF is -1, and therefore $FF00 is -256, the initial DEC instruction on the high byte is precisely correct to compute (LVAL+$FF00) + N'. The middle code computes the final sum, with the BCS/INC easily handling any carry that may need to be propegated.

Quote:
Sorry for that!


Not a problem; without a clearly written message it was kind of hard to get, but everyone does it. I do too.


Top
 Profile  
Reply with quote  
PostPosted: Sun May 21, 2006 4:25 pm 
Offline

Joined: Sun Sep 15, 2002 10:42 pm
Posts: 214
Code:
          LDX #$00
          LDA TEMP1 ; signed 8 bit number
          CMP #$00
          BPL .CONT
          DEX ; bit 7 was set, so it's a negative
.CONT     CLC
          ADC LVALL
          STA LVALL ; update the stored number low byte
          TXA
          ADC LVALH
          STA LVALH ; update the stored number high byte
          RTS


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 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: