| |
ready.
Registered: Feb 2003 Posts: 441 |
64tass: labels inside FOR ... NEXT loops
hello,
does 64tass have the possibility to use indexed labels, like inside a FOR...NEXT loop?
Something like:
.FOR X=0, X<X_MAX-1, X=X+1
LABEL(X)
LDA #ABC
STA ZXY
.NEXT
so to have X_MAX labels.
Unrolled:
LABEL1
LDA #ABC
STA ZXY
LABEL2
LDA #ABC
STA ZXY
..... |
|
| |
iAN CooG
Registered: May 2002 Posts: 3193 |
The generated code length is constant so something like this should work, use a calc to access to label+offset
*=$1000
X_MAX=6
.FOR X=0, X<X_MAX, X=X+1
.if X == 0
label
.fi
LDA #X
STA $8000+X
.if X == 0
endcode
.fi
.NEXT
size=endcode-label
rts
.word label+0*size
.word label+1*size
.word label+5*size
generated listing
=6 X_MAX=6
.1000 label
.1000 a9 00 lda #$00 LDA #X
.1002 8d 00 80 sta $8000 STA $8000+X
.1005 endcode
.1005 a9 01 lda #$01 LDA #X
.1007 8d 01 80 sta $8001 STA $8000+X
.100a a9 02 lda #$02 LDA #X
.100c 8d 02 80 sta $8002 STA $8000+X
.100f a9 03 lda #$03 LDA #X
.1011 8d 03 80 sta $8003 STA $8000+X
.1014 a9 04 lda #$04 LDA #X
.1016 8d 04 80 sta $8004 STA $8000+X
.1019 a9 05 lda #$05 LDA #X
.101b 8d 05 80 sta $8005 STA $8000+X
=5 size=endcode-label
.101e 60 rts rts
>101f 00 10 .word label+0*size
>1021 05 10 .word label+1*size
>1023 19 10 .word label+5*size
|
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
its not much more complicated natively, if you gen the code to loc zp:
lda zplo
sta labelslo,x
lda zphi
sta labelshi,x
or if the distance is constant just a 16 bit add in the other speedcode gen. |
| |
Hein
Registered: Apr 2004 Posts: 954 |
It used to work in older versions, but seems broken in the new version.
old version:
mymacro .macro
label\1 lda #\1
.endm
.for i=0,i<8,i=i+1
#mymacro ^i
.next
then
lda #0
sta label0+1
sta label1+1
etc.
I tried it in the new version with:
.for i=0,i<8,i=i+1
#mymacro i
.next
but the i isn't passed on to labels, but it is to the value.. :/ |
| |
soci
Registered: Sep 2003 Posts: 480 |
The "^" prefix for macro parameters is gone since r98. It did an expression evaluation and the result was converted to a decimal string which in turn was used for textual replacement. Similar to the "^" operator.
While it could be resurrected I'd like to see it dead and buried. Unfortunately the non-macro operator variant of this can't go away that easy due to it's common use in basic start lines. The sad thing is there's no other useful use of it at all. It should have been assigned as the bank byte operator but it couldn't due to it's 1.3x legacy.
As macro parameters are text replacements you're out of luck to use the value of the loop variable this way.
The alternative to numbered labels is lists. Simplest is to collect addresses into a list:
*= $1000
lista := [] ; empty
.for i=0,i<8,i=i+1
lista ..= [*] ; collect
lda #i
.if i>3
nop
.fi
.next
.word lista ;all
.word lista[4];5th Gives:
.1000 a9 00 lda #$00 lda #i
.1002 a9 01 lda #$01 lda #i
.1004 a9 02 lda #$02 lda #i
.1006 a9 03 lda #$03 lda #i
.1008 a9 04 lda #$04 lda #i
.100a ea nop nop
.100b a9 05 lda #$05 lda #i
.100d ea nop nop
.100e a9 06 lda #$06 lda #i
.1010 ea nop nop
.1011 a9 07 lda #$07 lda #i
.1013 ea nop nop
>1014 00 10 02 10 04 10 06 10 .word lista ;all
>101c 08 10 0b 10 0e 10 11 10
>1024 08 10 .word lista[4];5th
Something similar can be done a bit more complicated using a list of anonymous scopes (not exactly the same as above):
*= $1000
lista := []
.for i=0,i<8,i=i+1
lista ..= [+]
+ .block
label lda #i
.if i>3
lbl2 nop
.fi
.bend
.next
.word lista.label
.word lista[4].lbl2
Results in:
.1000 a9 00 lda #$00 label lda #i
.1002 a9 01 lda #$01 label lda #i
.1004 a9 02 lda #$02 label lda #i
.1006 a9 03 lda #$03 label lda #i
.1008 a9 04 lda #$04 label lda #i
.100a ea nop lbl2 nop
.100b a9 05 lda #$05 label lda #i
.100d ea nop lbl2 nop
.100e a9 06 lda #$06 label lda #i
.1010 ea nop lbl2 nop
.1011 a9 07 lda #$07 label lda #i
.1013 ea nop lbl2 nop
>1014 00 10 02 10 04 10 06 10 .word lista.label
>101c 08 10 0b 10 0e 10 11 10
>1024 0a 10 .word lista[4].lbl2
This has an advantage that proper referencable labels can be used for each instance of code using only one list.
I think I've showed Oswald once in private message how to prototype 25 parametrized IRQs with a for loop generator so that each of them sets the vector to the next one and the last one back to the first. With on-demand high byte update to spare cycles/bytes (variable length instances) and initial setup. It used this latter anonymous scope+list method. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
for the record:
*= $801
.word +, 2016
.null $9e, ^start
+ .word 0
start
sei
lda #<irqlist[0].addr ; elso cim
sta $314
lda #>irqlist[0].addr
sta $315
lda #irqlist[0].raster ; elso pozicio
sta $d012
lda $d011
and #~$80
sta $d011
lda #1
sta $dc0d
sta $d01a
bit $dc0d
sta $d019
cli
rts
irqlist2 := [] ; ures lista a rutinoknak
.for this = 0, this < 50, this = this + 1; 50 db
irqlist2 ..= [+] ; aktualis irq rutin listaba rakasa
+ .block ; irq rutin blokk
addr = * ; cim
raster = (this & 1) == 0 ? (this/2)*8+53 : (this/2)*8+55; raster pozicio effekthez
nextirq = irqlist[len(irqlist2) % len(irqlist)];a kovetkezo irq rutin
lda #this & 15 ; hogy legyen valami effekt is
sta $d020
lda #nextirq.raster ; kovetkezo pozicio
sta $d012
inc $d019
lda #<nextirq.addr ; kovetkezo cim
sta $314
.if (>nextirq.addr) != (>addr); csak ha kell
lda #>nextirq.addr
sta $315
.fi
jmp this == 49 ? $ea31 : $ea81; hogy lehessen gepelni ;)
.bend
.next
irqlist = irqlist2 ; hogy lehessen hasznalni fent |
| |
soci
Registered: Sep 2003 Posts: 480 |
Thanks! Next time I'll comment in English, one can never know ;) |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
Parenthetical: A great example of why code comments and symbols always should be in English - you never know who is going to read the code down the line.
I take it one step further and keep all design documents, Trello boards et cetera in English as well, even though at the moment everyone in the group speaks Swedish. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
*= $801
.word +, 2016
.null $9e, ^start
+ .word 0
start
sei
lda #<irqlist[0].addr ; first adress
sta $314
lda #>irqlist[0].addr
sta $315
lda #irqlist[0].raster ; first raster pos
sta $d012
lda $d011
and #~$80
sta $d011
lda #1
sta $dc0d
sta $d01a
bit $dc0d
sta $d019
cli
rts
irqlist2 := [] ; empty list for the routines
.for this = 0, this < 50, this = this + 1; 50 pcs
irqlist2 ..= [+] ;put current irq routine into list
+ .block ; irq routine block
addr = * ; address
raster = (this & 1) == 0 ? (this/2)*8+53 : (this/2)*8+55; raster position for effect
nextirq = irqlist[len(irqlist2) % len(irqlist)];the next irq routine
lda #this & 15 ; so some effect is shown
sta $d020
lda #nextirq.raster ; next position
sta $d012
inc $d019
lda #<nextirq.addr ; next adress
sta $314
.if (>nextirq.addr) != (>addr); only if needed
lda #>nextirq.addr
sta $315
.fi
jmp this == 49 ? $ea31 : $ea81; so you can type ;)
.bend
.next
irqlist = irqlist2 ; so it is possible to use up there |
| |
chatGPZ
Registered: Dec 2001 Posts: 11386 |
Quote:A great example of why code comments and symbols always should be in English
come on.... at least its not japanese :) |
| |
Hein
Registered: Apr 2004 Posts: 954 |
Quoting soci
*= $1000
lista := [] ; empty
.for i=0,i<8,i=i+1
lista ..= [*] ; collect
lda #i
.if i>3
nop
.fi
.next
.word lista ;all
.word lista[4];5th
Thanks, will try that. |
... 18 posts hidden. Click here to view all posts.... |
Previous - 1 | 2 | 3 - Next |