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.

screenshot

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
addq.l	#8,a3             ; increment cyclecop address by 8
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....    *"

Amiga Machine Code Course

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

Next post: Amiga Machine Code Letter VIII - Audio.

Mark Wrobel
Mark Wrobel
Team Lead, developer and mortgage expert