
 ASSEMBLER TRICKS No.2

 So,here we go with the second issue of my little serie of articles. This
 time I'll talk about a well-known thing called vertical and horizontal
 scroll. There are many ways to do them. When you have to code a vertical
 scrollroutine, the best thing could seem to use the blitter, but I think
 that would be the longest way. So here's something else: simply use the
 bitplanes pointers!
 Let's consider you wanna scroll a four bitplane screen upwards. In the
 copperlist you have the various bitplanes' pointers. All you have to do
 is simply making visualize a row upwards every time and you can do it
 by increasing the copper counter values. Here's a short example. Let's
 imagine that your screen is 320 pixels wide and 256 pixels high.
 Every pixel is a bit , so 320 pixels are 320/8 bytes, this means 40 bytes
 ($28). Let's imagine that the picture was loaded from $40000. So the
 copperlist should look like this:

 dc.w $00e0,$0004,$00e2,$0000   ; this is 1st bitplane
 dc.w $00e4,$0004,$00e6,$2800   ; second bitplane: infact 40 bytes * 256
                                ; scan lines = 1024 bytes = $2800
 dc.w $00e8,$0004,$00ea,$5000
 dc.w $00ec,$0004,$00ee,$7800

 and the other things like colours and so on...
 The values you are interested for are $0000,$2800,$5000,$7800 this means
 the low-bitplane pointers. Every frame you must decrease them by $28.
 Of course to do this every pointer should have a name, so the new copper
 list should look like this:

 dc.w $00e0,$0004,$00e2
 bpl1: $0000,$00e4,$0004,$00e6
 bpl2: $2800,$00e8,$0004,$00ea
 bpl3: $5000,$00ec,$0004,$00ee
 bpl4: $7800

 To scroll upwards your routine (to be called avery vb frame) should look
 like this:

 ScrollUpwards:

 sub.w #$28,bpl1
 sub.w #$28,bpl2
 sub.w #$28,bpl3
 sub.w #$28,bpl4
 rts

 Of course you can create counters so that once reached a value the scroll
 restarts from $40000 and so on. To scroll downwards the thing to do is
 just the same! But of course instead of decreasing you must increase the
 values.
 The horizontal scroll is a bit harder, becausem as you read before, a row
 is 40 bytes (or more for larger pictures) but a pixel is one bit and
 therefore you must operate with bits and not with bytes. So the operations
 aren't anymore add and sub but lsr and lsl (but inly ATARI-ST CODERS do
 scrolls with logic shifts! -ed-).
 But there's another way to do it and it's to combinate an addition/subtract
 of 1 byte to the copperlist values (as you've seen before) using the 
 $dff102 (delay) register. This way seems to be rather complicate especially
 when you have many bitplanes to handle. The third (and the BEST! -ed) way
 is to use the BLITTER (yeah! -ed-).
 This is the routine: of course before remember to turn on the blitter and
 so on. Call it every vertical blanking interrupt:


 
Scroll:

move.w	#4,d0                   ; number of bitplanes to scroll
move.l	#$50000,a1              ; pointer to the piccy

Doit:
Wtbl:
btst	#$0e,$dff002            ; wait blitter
bne	wtbl
move.w	#$c9f0,$dff040          ; bltcon0. In this case the speed
move.w	#$0000,$dff042          ; bltcon1
move.l	#$ffffffff,$dff044      ; mask
move.l	#$00000000,$dff064      ; modulo (0 bcoz it's 320 pixels)
move.l	a1,a2
move.l	a2,$dff054              ; pointer to destination d
add.l	#$02,a2                 ; important: 0 scrolls rightwards
                                ;2 scrolls leftwards

move.l	a2,$dff050              ; pointer to source a
move.w	#$0c16,$dff058          ; start blitter. This size scrolls
                                  just a little piece of the screen.
add.w	#$2800,a1               ; go to next bitplane
sub.w	#$0001,d0               ; check if all bplanes are scrolled
bne	doit                    ; otherwise scrolls the next one
rts


 In this routine the SOURCE A and the DESTINATION D registers of the
 blitter point to the same address, but of course you can use differnt
 addresses. For example load the piccy to $40000 and scroll it to $50000.
 Don't forget that the copperlist pointers must point to $50000,of course!
 Well, I think that's all for this issue. Hope you'll enjoy doing bullshit
 with the blitter next time you wanna code something. Bye!

                                           Filippetto of Savage

