| |
Flashback
Registered: Dec 2009 Posts: 4 |
Want to understand this way of looping through a table
Hi,
I would like some explanation about this way of looping a colour table:
colourcycle.asm
Basically it's this section I can't wrap my head around:
...
txa ; select next colour index
adc #01
and #07 ; loop colour index
tax
...
colours .byte 09, 08, 05, 13, 01, 13, 05, 08 ; colour table
As far as I understand, the start color is saved in a ZP address (startcol) which will is changed each frame. This is done by txa/ adc #$01 I guess. (BTW, why is there no clc before adc here?) But why do we need the and #$07?
Regards |
|
... 27 posts hidden. Click here to view all posts.... |
| |
Bitbreaker
Registered: Oct 2002 Posts: 501 |
i'd favour using sbx aswell when it is about incrementing x by any number and pplying an and operation.
Another option is to move the end condition of the loop into the table, and wrap the index depending on that. Color-register writes usually only need the lownibble.
...
lda tab,x
bpl +
ldx #$ff
+
inx
...
tab !byte 9,8,5,13,1,13,5,$f8
|
| |
chatGPZ
Registered: Dec 2001 Posts: 11147 |
Or just count the index backwards :) |
| |
Gordian
Registered: May 2022 Posts: 36 |
Another approach:
ldx index
...
lda #7
inx
sax index |
| |
Copyfault
Registered: Dec 2001 Posts: 467 |
I'd say it won't get any shorter than doing it via sbx...
Hmm, maybe your table values allow for getting rid of that "lda #$07", but this only works for specific values, just as Bitbreaker mentioned in his post above. |
| |
Gordian
Registered: May 2022 Posts: 36 |
Yes, not shorter, just another solution.
If accumulator is utilized before LDA or it's just not needed anymore, there are no cons.
Or LDY is used for getting values. |
| |
Frostbyte
Registered: Aug 2003 Posts: 174 |
If you need to persist the value, is Gordian's solution then the shortest?
ldx zp_val // 3
lda #$07 // 2
sbx #$ff // 2
stx zp_val // 3
// ... // X = 1 to 8 here
// 8b, 10c
vs.
ldx zp_val // 3
// ... // X = 0 to 7 here
lda #$07 // 2
inx // 2
sax zp_val // 3
// ... // X = 1 to 8 here
// 7b, 10c |
| |
Copyfault
Registered: Dec 2001 Posts: 467 |
Quoting FrostbyteIf you need to persist the value, is Gordian's solution then the shortest?
ldx zp_val // 3
lda #$07 // 2
sbx #$ff // 2
stx zp_val // 3
// ... // X = 1 to 8 here
// 8b, 10c
vs.
ldx zp_val // 3
// ... // X = 0 to 7 here
lda #$07 // 2
inx // 2
sax zp_val // 3
// ... // X = 1 to 8 here
// 7b, 10c Yes, it's one byte shorter when you take the store commands to some temporary register into account. My thinking was about a loop that does not change X in its inner part, thus without any need for storing it inbetween. |
| |
Gordian
Registered: May 2022 Posts: 36 |
Hi!
As I wrote above, lda #$07 can be moved outside inner loop:
lda #$07
ldx zp_val
;ldy table_value,x
;sty somewhere
inx
sax zp_val
So we have 2b and 2c shorter version. |
| |
Copyfault
Registered: Dec 2001 Posts: 467 |
Quoting GordianHi!
As I wrote above, lda #$07 can be moved outside inner loop:
lda #$07
ldx zp_val
;ldy table_value,x
;sty somewhere
inx
sax zp_val
So we have 2b and 2c shorter version. In some rare cases, this might be possible, but usually accu is needed in an inner loop. I still think it'd be more feasible to get rid of the ldx/stx-opcodes (not saying that this is easier than to avoid usage of the accu in the inner loop). In the end, it all depends on what your loop is actually needed for. |
| |
Rastah Bar
Registered: Oct 2012 Posts: 336 |
A bit similar to what Bitbreaker and chatGPZ said, but X is not cluttered and it works for values other than colors too:
dec get_number:+1 ;6
bpl get_number: ;2/3
lda #max_index ;2
sta get_number:+1 ;4
get_number:
lda table
;table at page boundary
table
BYTE number1, number2, …
- Works for any table size < 130;
- Uses ((tabel size-1)*9 + 14)/(table size) cycles on average, which is smaller than 10 cycles for tables with more than 5 elements;
- X (and Y) is not cluttered. |
Previous - 1 | 2 | 3 | 4 - Next |