|
|
Copy Tile RoutineThe 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. 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. ExplanationFirst 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
|