![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
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 |