Heaven/TQA Posted June 28, 2013 Share Posted June 28, 2013 I would need an code which does an 'binary' AND #170 similar to an AND#$7f but my range is instead of 128 bytes 170 bytes... the value should wrap... so 171 should become 1. etc do_barfx2 cmp #2 bne do_barfx3 txa clc adc cloc tay lda barsin1,y clc adc #1 sec sbc cloc cmp #169 bcc *+5 sec sbc #169 ;and #$7f sta barpostab-1,x jmp parallax_cont Quote Link to comment Share on other sites More sharing options...
Chilly Willy Posted June 28, 2013 Share Posted June 28, 2013 (edited) That's called the modulous, and in C you would do: x = y % 170; It's slow on 8-bit systems... maybe someone knows an optimization for the 6502. Edited June 28, 2013 by Chilly Willy Quote Link to comment Share on other sites More sharing options...
Bryan Posted June 28, 2013 Share Posted June 28, 2013 Do you only want to do this for byte values? So.. 0=0 1=1 169=169 170=0 171=1 255=85 A simple way would probably be to build a 64 byte table: LDA Value BPL Skip ;Number is 127 or less LSR A TAX LDA tableaddr-64,X ROL A -Skip Since the low bit will not change (even numbers 170+ become even numbers 0+) we can save the low bit, look up one of 64 values, and then restore the low bit. Because bit 7 is guaranteed to be set and is then shifted down to bit 6, we read from a base offset of 64 bytes from the table. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 28, 2013 Author Share Posted June 28, 2013 range is 0-169... Bryan... what would the LUT look like? Quote Link to comment Share on other sites More sharing options...
MaPa Posted June 28, 2013 Share Posted June 28, 2013 256 byte look up table maybe? if you have space for it. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 28, 2013 Author Share Posted June 28, 2013 MaPa? but how to generate? still not get 100% what Bryan suggested Quote Link to comment Share on other sites More sharing options...
MaPa Posted June 28, 2013 Share Posted June 28, 2013 (edited) Simply bytes 0-169 followed by 0-85. If it's only for byte values, or do you need "and 170" 16bit number? :170 dta # :86 dta # or :256 dta #%170 Edited June 28, 2013 by MaPa Quote Link to comment Share on other sites More sharing options...
TMR Posted June 28, 2013 Share Posted June 28, 2013 i'm only half awake but... is this what you're looking for? ldx #0 lda #0 loop sta data_table,x clc adc #$01 cmp #170 bne *+$04 lda #$00 inx bne loop Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 28, 2013 Author Share Posted June 28, 2013 ok guys... maybe I had not enough coffe today but... Mapa & TMR... how does this wrap? when indexing through your tables... after 170 it goes back to 0 and then the 0-84 part starts... but when the 84 exceedes (wrap around 256) then I am not at 85 but at 0 again? or do I miss here some magic? Quote Link to comment Share on other sites More sharing options...
MaPa Posted June 28, 2013 Share Posted June 28, 2013 The question is... WHAT numbers you want to "AND #170" .. is it only bytes (0-255) or 16bit numbers (0-65535) or... ? Quote Link to comment Share on other sites More sharing options...
TMR Posted June 28, 2013 Share Posted June 28, 2013 (edited) when indexing through your tables... after 170 it goes back to 0 and then the 0-84 part starts... but when the 84 exceedes (wrap around 256) then I am not at 85 but at 0 again? or do I miss here some magic? It's a cheat to translate a number from $00 to $ff into something in the range, there's no allowance for the index wrapping around... If the index is constantly being added to or subtracted from, check it for 170 after each change and, if it goes over, subtract 170: txa cmp #170 bcc exit sec sbc #170 exit tax Not a really efficient solution of course but, unless you start using a 16-bit value and have a longer table to "clip" it, there's probably not a significantly faster one...? Edited June 28, 2013 by TMR Quote Link to comment Share on other sites More sharing options...
xxl Posted June 28, 2013 Share Posted June 28, 2013 (edited) txa cmp #170 bcc exit sec sbc #170 exit tax maybe this? cpx #170 bcc exit txa sbx #170 Edited June 28, 2013 by xxl 1 Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 28, 2013 Author Share Posted June 28, 2013 do_barfx2 cmp #2 bne do_barfx3 txa clc adc cloc tay lda barsin1,y clc adc #1 sec sbc cloc cmp #169 bcc *+5 sec sbc #169 ;and #$7f sta barpostab-1,x jmp parallax_cont again... where is my error then TMR? Quote Link to comment Share on other sites More sharing options...
TMR Posted June 28, 2013 Share Posted June 28, 2013 Where is my error then TMR? It's probably the SBC, what we're talking about pretty much only works when adding so if we follow the logic through this... 166+24=190 190-170=20 ...makes sense but this... 6-24=238 238-170=68 ...doesn't, it should be 152. But i'm fairly sure we can work backwards from there so, If it's always going to be a subtraction at that point in the code, then checking for 170 and subtracting 86 if it's over will work instead as long as the values being subtracted don't get too high? In passing, this is why we try to go for steps with 64,128 or 256 workable states usually... =-) Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 28, 2013 Author Share Posted June 28, 2013 Well as you already know I got 128 done but I want to stretch to the max... and that's why I need 170 Quote Link to comment Share on other sites More sharing options...
Rybags Posted June 28, 2013 Share Posted June 28, 2013 Optimization can be had in that the CMP leaves the carry in a known state due to program flow - so you can omit the following SEC. If it's the case you need the carry the other way, you can just adjust how much you add or subtract. Quote Link to comment Share on other sites More sharing options...
NRV Posted June 29, 2013 Share Posted June 29, 2013 I suppose is already clear, but: - if you add something to your value you need to check if the result is greater or equal to 170, and in that case SUBSTRACT 170 - if you substract something to your value you need to check if the result is below 0, and in that case ADD 170 ... there is no "one magic table".. but you can have two tables, one for the case you just added something to your value, and the other for the case you just substracted something (if you don't mind losing 512 bytes for this... or less, if you compare with 170 before using the tables). ; if you add something to your value in "A" clc adc #something bcs value_over_170 cmp #170 bcc exit1 value_over_170 sbc #170 ; the carry is already set! exit1 ... ; if you substract something to your value in "A" sec sbc #something bcs exit2 value_below_0 adc #170 ; the carry is already clear! exit2 ... (by the way.. if the value "something" is already greater or equal to 170, I would substract 170 from it before using this routines, if not I believe you need more code) (also I'm assuming that your value in "A" is already in the range 0 - 169 !!) With tables: ; add: clc adc something ; value already normalized! (between 0-169) bcc version2 ; the result was not greater than 255, use another table tax lda TabMod170AdcVersion1,x bcs continue ; always jump! tax lda TabMod170AdcVersion2,x continue ... ; substract: sec sbc something ; value already normalized!(between 0-169) tax lda TabMod170SbcVersion,x Well they were 3 tables, it was more complex than I was expecting.. shame on you Heaven! But I suppose we can combine all tables into a big one.. let's see.. TabMod170SbcVersion --> 256 byte values: [84-169], [0-169] TabMod170AdcVersion1 --> 256 byte values: [86-169], [0-169],[0-1] TabMod170AdcVersion2 --> 256 byte values: [0-169], [0-85] Yep.. is easy to combine them in one table of 86+170+86 bytes (but you lose some cycles because of the page boundaries crossed).. homework (and yep.. probably is better to just use the "without tables" version of this routines, at least the one for "adding") (I didn't check this too much, there could be errors!) Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 29, 2013 Author Share Posted June 29, 2013 Ok... One missing point here... I am adding/subtracting different values to get nice movements for something as you can see in the snippet... So how can I see if I need the add or sub method? Quote Link to comment Share on other sites More sharing options...
NRV Posted June 29, 2013 Share Posted June 29, 2013 (edited) Ok... One missing point here... I am adding/subtracting different values to get nice movements for something as you can see in the snippet... So how can I see if I need the add or sub method? You lost me there (I should be sleeping) Why do you not now if you are adding or subtracting a value? I mean... if you just did "adc value" you were adding, if you did "sbc value" you were subtracting.. (in your code I see that you use adc cloc or sbc cloc). Or are you just adding values that can be positive or negative? (255 for -1 for example) Edited June 29, 2013 by NRV Quote Link to comment Share on other sites More sharing options...
MaPa Posted June 29, 2013 Share Posted June 29, 2013 Hmm I don't get it what are you trying to do. Can you explain it? Is it that you have a value 0-169 then add/sub some number from it and you want have result within 0-169 again? How big numbers are you adding/substracting? If it's max. +/-43 you can use the 256 byte table. :170 dta # :43 dta # :43 dta 170-43+# Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 29, 2013 Author Share Posted June 29, 2013 I was adding/subtracting several sin values plus adding offset to pick up one grafix line from an lookup table Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 29, 2013 Author Share Posted June 29, 2013 And gfx is 170 linea Quote Link to comment Share on other sites More sharing options...
Bryan Posted June 29, 2013 Share Posted June 29, 2013 range is 0-169... Bryan... what would the LUT look like? The table would be every even value from 128 to 254, shifted down 1: 128->64, 130->65 ... 168->84, 170->0, 172->1... the whole code: LDA Value BPL Skip ;Number is 127 or less LSR A TAX LDA tableaddr-64,X ROL A -Skip ... tableaddr .byte 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84 .byte 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 .byte 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 Of course, a compare and subtraction avoids the table and is about as quick. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted June 29, 2013 Author Share Posted June 29, 2013 So what about actually comparing actual calculation with the previous one? If it is greater the treat it like an add and otherwise like an sbc? Quote Link to comment Share on other sites More sharing options...
NRV Posted June 29, 2013 Share Posted June 29, 2013 Arrrgh.. I still don't get your problem x) I think you fail to answer the important questions, for one what is the range of the numbers that you are adding or subtracting? from 0 to what? I was adding/subtracting several sin values plus adding offset to pick up one grafix line from an lookup table With this I still don't see the problem.. if you just added something you use the method that I put for "add", if you subtract something you use the other one.. So what about actually comparing actual calculation with the previous one? If it is greater the treat it like an add and otherwise like an sbc? Why should you need to do that? if you just added something treat it like and add! (and viceversa) Come on Heaven, help us to help you (and the MaPa solution is a very good one if the numbers you are adding or subtracting are in the range 0-43) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.