The Lush Engine








Introduction
Background
Math
Objects
Palettes
Tiles
Introduction
copytile.asm
Utilities

Copy Tile Routine

The following file is a routine to allow for easy copying of tile data to the various tile areas. You can download the file as well if you don't want to cut and paste the text.

copytile.asm

To download the file using a PC, right-click the link and select the option "Save Target As" then save the file as you would any other file from windows.

Explanation

First of all, we need to make sure that we will be writing to the correct tile bank. So we write the bank number into the bank selector register.

Now we need to set up a pointer to the start of the correct tile set. We will be writing data to either the low set (starting at $8000 and the tiles are numbered 0 to 255) or the high set (starting at $8800 and the tiles are numbered -128 to 127 with 0 being at $9000).

We set HL to point to the start of the appropriate set, and if we are using the high set, we add 128 to the tile number to turn it into a number from 0 to 255.

Now we preserve registers D and E, as we are going to use them for a quick loop to move HL to point to the start of the first tile we are copying.

The loop will add the tile number to HL sixteen times. This is because a single tile takes up 16 bytes, and the quickest loop is to add the tile number 16 times. Granted, if we are using tiles 0-15, then it would be quicker the other way around, but that's something that you could improve on for your own code.

Once we've moved the pointer to the correct place, we can restore registers D and E. Now we get to copy the actual data into the correct place. So, a quick loop copying 16 bytes per tile does this for us.

Source

;*****************************************************************
; Procedure Name  : copy_tile_data
;
; Author          : Marc Gale (Xalthorn or Eldara)
;
; Description     : This procedure is designed to copy data from
;                   the cartridge ROM to the required place in
;                   one of the banks of tile data.
;
; On Entry        : bc holds a pointer to the source data
;                   a holds the bank number (0 or 1)
;                   h holds the set number (0=low set, 1=high set)
;                   d holds the tile number
;                   e holds the number of tiles to copy
;
; During          : All registers are used
;
; On Exit         : Nothing intentional
;*****************************************************************
copy_tile_data:
 and    1               ; clear all but the last bit
 ldh    [$4F],a         ; select the bank

 ld     a,h             ; get the set number
 and    1               ; mask out all but bit 0
 cp     0               ; is it set 0 (the first set)
 jr     nz,.highset     ; if it isn't, do the highset part
.lowset:
 ld     hl,$8000        ; set the pointer to the lowset
 jr     .doneset        ; we've done the set pointer, carry on
.highset:
 ld     hl,$8800        ; set the pointer to the highset
 ld     a,d             ; get the tile number (-128 to 127)
 add    a,128           ; add 128 to it
 ld     d,a		; put it back in d
.doneset:

 push   de              ; we need to preserve these for a moment
                        ; we're going to use e as a loop to
                        ; quickly move the data pointer to the
                        ; right place.
 ld     e,16
.point_loop
 ld     a,l             ; get the low byte of the pointer
 add    a,d             ; add the tile number
 ld     l,a             ; put it back
 ld     a,0             ; clear a
 adc    a,h             ; add (with carry) a and h
 ld     h,a             ; put it back
 dec    e               ; decrease e by one
 jr     nz,.point_loop  ; if we've not reached the end, carry on

 pop    de              ; grab the old data back

; now we can copy the actual data.

.main_loop
 ld     d,16            ; there are 16 bytes per tile
.copy_loop
 ld     a,[bc]          ; get a byte of data
 ld     [hli],a         ; put it at the target and increment hl
 ld     a,c             ; get the low byte
 add    a,1             ; add 1 to c
 ld     c,a             ; put it back
 ld     a,0             ; clear a
 adc    a,b             ; add (with carry) a and b
 ld     b,a             ; put it back
 dec    d
 jr     nz,.copy_loop   ; if we've not reached the end, keep going
 dec    e               ; decrease the counter
 jr     nz,.main_loop   ; if we've not reached the end, keep going

 ret

Buttons created using the interactive button maker at Coolarchive