Amiga Machine Code Letter VII - Colorcycling

Amiga Machine Code - Letter VII

We have reached Letter VII of the Amiga Machine Code course. As always, make sure to read the letter, since I won’t go through all the details.

The theme of this post, is to use color cycling, to make the text scrolling program from the previous post, a little more interesting. The end result looks like this.

The screenshot shows a lot of nice colors, where we have the scrolling text. It’s kind of an unintuitive result at first, since the program is using one bitplane that only provides two colors. However, we see many more colors, and that’s all thanks to the copper, that adds more colors as a sort of post processing. It’s quite enginous when you think about it.

The code listing, mc0702, from Disk1 adds a little cycle routine to the program, mc0701, shown in the previous post. Let’s take a look at it!

The Cycle Routine

The cycle routine extends the copper list, so that COLOR01 can be set for each line of the characters. By doing so, each line will get a different color, even though there’s only a single bitplane.

The colors for each line are determined by a lookup into a color table.

cyclecnt:
dc.w	$0000 ; allocate for cycle counter cycle: ; The cycle routine lea.l cyclecnt,a1 ; move cyclecnt address into a1 move.w (a1),d1 ; move cyclecnt value into d1 addq.w #2,(a1) ; add 2 to cyclecnt, but not to d1! cmp.w #96,d1 ; compare 96 with cyclecnt value in d1 bne notround ; if not 96 then go to notround clr.w (a1) ; set cyclecnt value to zero clr.w d1 ; set d1 to zero notround: lea.l cycletable,a2 ; move cycletable address into a2 lea.l cyclecop,a3 ; move cyclecop address into a3 moveq #19,d0 ; move 19 into d0 - cycleloop counter cycleloop: ; do this loop 20 times move.w (a2,d1.w),6(a3) ; put value in cycletable address + cycle counter into the 6th word of the cyclecop setting the$DFF182 COLOR01
addq.w	#2,d1             ; increment cycle counter by 2
dbra	d0,cycleloop      ; if not d0 < -1 then goto cycleloop

rts                       ; return from cycle routine


The cyclecnt acts as an offset into the color lookup table, that is incremented each time the cycle routine is called. The cyclecnt is reset, when it reaces a value of 96. The reason is, that the color lookup table only is 136 bytes long, and if we subtract the last 20 colors (40 bytes), we get 96 bytes.

Inside the cycle routine itself, there’s a loop that iterates 20 times. At each iteration it sets a color in the copperlist cyclecop, taken from the color lookup table, with an offset defined by cyclecnt.

cyclecop:            ; visible screen starts at line 2c
dc.w	$c201,$fffe  ; wait for line 194 ($c2-$2c = $96 = 150 visible line) dc.w$0182,$0000 dc.w$c301,$fffe ; wait for line 195 dc.w$0182,$0000 dc.w$c401,$fffe ; wait for line 196 dc.w$0182,$0000 dc.w$c501,$fffe ; wait for line 197 dc.w$0182,$0000 dc.w$c601,$fffe ; wait for line 198 dc.w$0182,$0000 dc.w$c701,$fffe ; wait for line 199 dc.w$0182,$0000 dc.w$c801,$fffe ; wait for line 200 dc.w$0182,$0000 dc.w$c901,$fffe ; wait for line 201 dc.w$0182,$0000 dc.w$ca01,$fffe ; wait for line 202 dc.w$0182,$0000 dc.w$cb01,$fffe ; wait for line 203 dc.w$0182,$0000 dc.w$cc01,$fffe ; wait for line 204 dc.w$0182,$0000 dc.w$cd01,$fffe ; wait for line 205 dc.w$0182,$0000 dc.w$ce01,$fffe ; wait for line 206 dc.w$0182,$0000 dc.w$cf01,$fffe ; wait for line 207 dc.w$0182,$0000 dc.w$d001,$fffe ; wait for line 208 dc.w$0182,$0000 dc.w$d101,$fffe ; wait for line 209 dc.w$0182,$0000 dc.w$d201,$fffe ; wait for line 210 dc.w$0182,$0000 dc.w$d301,$fffe ; wait for line 211 dc.w$0182,$0000 dc.w$d401,$fffe ; wait for line 212 dc.w$0182,$0000 dc.w$d501,$fffe ; wait for line 213 dc.w$0182,$0000 ; copper end sequence dc.w$ffdf,$fffe ; wait($df,$ff) enable wait >$ff horiz
dc.w	$2c01,$fffe  ; wait($01,$12c)
dc.w	$0100,$0200  ; BPLCON0 disable bitplanes - older PAL chips
dc.w	$ffff,$fffe  ; end of copper


The copperlist cyclecop waits for screen lines starting at line 194 and ends at line 213. This corresponds to the visible screen lines 150 to line 169. That’s exactly one line for each line of the font characters. After each wait, it sets the color for that line. The cycle routine will write different colors into this list, taken from the lookup table cycletable.

cycletable:
dc.w	$0f00,$0e01,$0d02,$0c03,$0b04,$0a05,$0906,$0807
dc.w	$0708,$0609,$050a,$040b,$030c,$020d,$010e,$000f
dc.w	$000f,$011e,$022d,$033c,$044b,$055a,$0669,$0778
dc.w	$0887,$0996,$0aa5,$0bb4,$0cc3,$0dd2,$0ee1,$0ff0
dc.w	$0ff0,$0fe0,$0fd0,$0fc0,$0fb0,$0fa0,$0f90,$0f80
dc.w	$0f70,$0f60,$0f50,$0f40,$0f30,$0f20,$0f10,$0f00

dc.w	$0f00,$0e01,$0d02,$0c03,$0b04,$0a05,$0906,$0807
dc.w	$0708,$0609,$050a,$040b,$030c,$020d,$010e,$000f
dc.w	$000f,$011e,$022d,$033c


Putting it all together

The mc0702 program can be found on Disk1, so I won’t show the full listing here. The program is also very similar to mc0701 from the previous post.

With a base in the mc0701 program, adding colorcycling is straightforward operation.

Start by adding a call to the cycle subroutine just after the call to the scroll subroutine. Next add the cycle subroutine to the program e.g. just after the scroll subroutine.

Next add cyclecop at the end of the copperlist, but just above the copper end sequence, which I included in this listing. Last, but not least, add the cycletable to the end of the code.

In the mc0702 code listing, the text has been changed to the following:

text:
dc.b	"DETTE ER EN TEST AV EN SCROLL MED"
dc.b	" COLORCYCLING P\$ AMIGA....    *"


Previous post: Amiga Machine Code Letter VII - Blitting and Scrolling.

Next post: Amiga Machine Code Letter VIII - Audio.