6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Nov 23, 2024 12:49 pm

All times are UTC




Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3
Author Message
PostPosted: Sun Jul 26, 2020 9:51 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
I thought about mentioning the unsigned thing, but missed the chance. You might want to give Bruce's article a chance to sink into your brain.


That is my reference.

I am hoping to find something simpler. The working code currently looks like this:

Code:
                          00075 ; 100 for i =-6 to 6
 0B12                     00076 L00100:
                          00077          ifdef  __TRACE
                          00078          ldx    #<100
                          00079          lda    #>100
                          00080          jsr    Trace
                          00081          endif
                          00082          ifdef  __ATLIN
 0B12 A2 12           [2] 00083          ldx    #<L00100
 0B14 8E 11F9         [4] 00084          stx    ResLn_
 0B17 A2 0B           [2] 00085          ldx    #>L00100
 0B19 8E 11FA         [4] 00086          stx    ResLn_+1
                          00087          endif
                          00088
 0B1C 20 0CDD         [6] 00089          jsr    ForEnter
                          00090
 0B1F A0 04           [2] 00091          ldy    #4
 0B21 A9 3B           [2] 00092          lda    #<T00000
 0B23 91 1C           [6] 00093          sta    (Ptr0),Y
 0B25 C8              [2] 00094          iny
 0B26 A9 0B           [2] 00095          lda    #>T00000
 0B28 91 1C           [6] 00096          sta    (Ptr0),Y
                          00097
 0B2A C8              [2] 00098          iny
 0B2B A9 03           [2] 00099          lda    #<I_
 0B2D 91 1C           [6] 00100          sta    (Ptr0),Y
 0B2F C8              [2] 00101          iny
 0B30 A9 12           [2] 00102          lda    #>I_
 0B32 91 1C           [6] 00103          sta    (Ptr0),Y
                          00104
 0B34 A2 FA           [2] 00105          ldx    #<-6
 0B36 A0 FF           [2] 00106          ldy    #>-6
                          00107
 0B38 4C 0B60         [3] 00108          jmp    T00003
                          00109
 0B3B                     00110 T00000:
 0B3B A9 01           [2] 00111          lda    #<1
 0B3D 18              [2] 00112          clc
 0B3E 6D 1203         [4] 00113          adc    I_
 0B41 AA              [2] 00114          tax
 0B42 A9 00           [2] 00115          lda    #>1
 0B44 6D 1204         [4] 00116          adc    I_+1
 0B47 A8              [2] 00117          tay
                          00118
 0B48 38              [2] 00119          sec
 0B49 E9 00           [2] 00120          sbc    #>6
 0B4B F0 08 (0B55)  [2/3] 00121          beq    3f
 0B4D 50 02 (0B51)  [2/3] 00122          bvc    2f
 0B4F 49 80           [2] 00123          eor    #$80
                          00124
 0B51                     00125 2:
 0B51 30 0B (0B5E)  [2/3] 00126          bmi    T00002
 0B53 10 06 (0B5B)  [2/3] 00127          bpl    T00001
                          00128
 0B55                     00129 3:
 0B55 E0 06           [2] 00130          cpx    #<6
 0B57 90 05 (0B5E)  [2/3] 00131          blo    T00002
 0B59 F0 03 (0B5E)  [2/3] 00132          beq    T00002
                          00133
 0B5B                     00134 T00001:
 0B5B 4C 0D37         [3] 00135          jmp    ForExit
                          00136
 0B5E                     00137 T00002:
 0B5E 68              [4] 00138          pla
 0B5F 68              [4] 00139          pla
                          00140
 0B60                     00141 T00003:
 0B60 8E 1203         [4] 00142          stx    I_
 0B63 8C 1204         [4] 00143          sty    I_+1
                          00144


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 26, 2020 10:06 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
I haven't tested this, but I think you could try replacing:
Code:
T00000:
         lda    #<1
         clc
         adc    I_
         tax
         lda    #>1
         adc    I_+1
         tay

         sec
         sbc    #>6
         beq    3f
         bvc    2f
         eor    #$80

2:
         bmi    T00002
         bpl    T00001

3:
         cpx    #<6
         blo    T00002
         beq    T00002

T00001:
with something like
Code:
T00000:
         lda    #<1
         clc
         adc    I_
         tax
         lda    #>1
         adc    I_+1
         tay

         cpx    #<6
         sbc    #>6
         bvc    2f
         eor    #$80

2:
         bmi    T00002

T00001:

_________________
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  
PostPosted: Sun Jul 26, 2020 10:16 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
That looks great! I'll have to try it.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jul 26, 2020 11:31 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
BillG wrote:
That looks great! I'll have to try it.

I was a bit hasty with that, because I think I'm looping for index < limit and BASIC loops for index <= limit for positive steps. For negative steps, we can replace the bmi with a bpl and be done, but for positive steps I think we need to revise the code thus:
Code:
T00000:
         lda    #<1
         clc
         adc    I_
         tax
         lda    #>1
         adc    I_+1
         tay

         cpx    #<6
         bne    1f
         eor    #>6
         beq    T00002      ; loop if index = limit
         tya
1:
         sbc    #>6
         bvc    2f
         eor    #$80

2:
         bmi    T00002      ; loop if index < limit

T00001:


You can choose your own behavior for a step of zero ... I think I have seen different treatments.

Attachment:
step0.PNG
step0.PNG [ 10.67 KiB | Viewed 801 times ]


Attachment:
step0v2.PNG
step0v2.PNG [ 9.26 KiB | Viewed 800 times ]

_________________
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  
PostPosted: Mon Jul 27, 2020 1:34 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
I was a bit hasty with that, because I think I'm looping for index < limit and BASIC loops for index <= limit for positive steps. For negative steps, we can replace the bmi with a bpl and be done,


In the 6800 example viewtopic.php?p=77251#p77251 the sign of the step is tested to select the appropriate comparison to exit the loop. The 680x has a TST instruction but the 6502 does not. However, the BIT instruction is perfect for checking the sign of a byte in memory.

barrym95838 wrote:
You can choose your own behavior for a step of zero ... I think I have seen different treatments.


I think it is best to not bother checking for a zero step; maybe the programmer wanted an endless loop.

You may have noticed that a trace capability is provided for diagnosing such things; defining __TRACE during assembly turns it on.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 27, 2020 8:54 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
Code:
         eor    #>6
         beq    T00002      ; loop if index = limit
         tya



It took a bit of thinking to realize you were doing a comparison without affecting the carry flag...

So for an up counting loop with a constant limit, use the shortcut repeat if < code, but comparing against limit + 1 unless the limit is $7FFF then do it your new way. A limit in a variable or expression cannot use the shortcut either.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 27, 2020 11:57 am 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
You can choose your own behavior for a step of zero ... I think I have seen different treatments.


I see what you mean. When the step value is zero, is it an up or a down counting loop when testing the end condition?

Arbitrarily declare that 0 is treated as up counting. If a programmer wants to play tricks like that, they should make their own loop with GOTO and IF statements; it will probably be easier to understand.

There is another complication: overflow of the loop counter. Unless something special is done, there is no way to stop a loop at 32767 ($7FFF) as adding the step overflows to -32768 ($8000). And it is not only the discontinuity at $7FFF/$8000 either since the step can be any value.

The algorithm for terminating an upward counting loop has to be something like:

Code:
if the loop variable before adding the step < 0 or the terminating value < 0:
   do a signed comparison
else:
   do an unsigned comparision


The opposite would be true for a downward counting loop.

Things could get very ugly since the terminating and step values may be in variables manipulated by the loop body.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 27, 2020 3:21 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1949
Location: Sacramento, CA, USA
I think there are a few strategies to combat the overflow problem. The one I've seen most often is to treat all INTs as signed and to do a quick overflow check when updating the loop counter, exiting instead of erroring out if true.

Checking for index < limit+1 instead of index <= limit is a clever hack, but loses 32767 as a valid limit unless you special-case it.

_________________
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  
PostPosted: Mon Jul 27, 2020 5:57 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
I think there are a few strategies to combat the overflow problem. The one I've seen most often is to treat all INTs as signed and to do a quick overflow check when updating the loop counter, exiting instead of erroring out if true.

Checking for index < limit+1 instead of index <= limit is a clever hack, but loses 32767 as a valid limit unless you special-case it.


I implemented index < limit+1 for constant limits with 32767 as a special case and realized the overflow problem when a loop would not stop at 32767. Any solution will cause slow down when using a variable or expression for the limit due to the extra processing necessary.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jul 27, 2020 7:30 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
barrym95838 wrote:
I think there are a few strategies to combat the overflow problem. The one I've seen most often is to treat all INTs as signed and to do a quick overflow check when updating the loop counter, exiting instead of erroring out if true.


I failed to see this earlier due to lack of sleep.

A bvs to the loop exit after adding the upper bytes does the job easily and effectively.

Thank you.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jul 28, 2020 9:25 pm 
Offline

Joined: Thu Mar 12, 2020 10:04 pm
Posts: 704
Location: North Tejas
I am able to run this test program now...

Code:
100 M=6:N=-257
1000 print "Testing for I = -257 to 6...";
1010 gosub 29000
1020 for I = -257 to 6
1030 print I;
1040 next I
1050 print
2000 print "Testing for I = 32760 to 32767...";
2010 gosub 29000
2020 for I = 32760 to 32767
2030 print I;
2040 next I
2050 print
3000 print "Testing for I = -257 to M...";
3010 gosub 29000
3020 for I = -257 to M
3030 print I;
3040 next I
3050 print
4000 print "Testing for I = 6 to -257 step -1...";
4010 gosub 29000
4020 for I = 6 to -257 step -1
4030 print I;
4040 next I
4050 print
5000 print "Testing for I = -32760 to -32768 step -1...";
5010 gosub 29000
5020 for I = -32760 to -32768 step -1
5030 print I;
5040 next I
5050 print
6000 print "Testing for I = 6 to N step -1...";
6010 gosub 29000
6020 for I = 6 to N step -1
6030 print I;
6040 next I
6050 print
7000 print "Testing for I = N+1 to M+1 step M-2...";
7010 gosub 29000
7020 N=1:M=3
7030 for I = N+1 to M+1 step M-2
7040 print I;
7050 next I
7060 print
8000 print "Testing for I = M+1 to N+1 step 2-M...";
8010 gosub 29000
8020 N=1:M=3
8030 for I = M+1 to N+1 step 2-M
8040 print I;
8050 next I
8060 print
20000 print "Tests complete"
20010 end
29000 rem ---------------------------------------------------------------------
29001 rem Read a line and end program if 'q'
29002 rem
29010 input line A$
29020 if ASC('Q') = ASC(A$) then end
29030 if ASC('q') = ASC(A$) then end
29040 return


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3

All times are UTC


Who is online

Users browsing this forum: No registered users and 18 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: