====== Decoding 4x4 tiles ====== by Achim If you use tile based maps for a game, you'll have to decode a whole screen first unless you want your scroll routine to scroll the background graphics onto the screen. Here's a piece of code that decodes 4x4 tiles to the screen. It colours the whole screen black (mc). Usually you've got two options: - Colour per tile - Colour per char The first option is very useful when you want to save rastertime for the main program, but is obviously less colourful. The second option is more colourful, but needs more rastertime when it comes to colour RAM shifting. Pseudo code for tile colouring: ldx actualTile lda attribtable,x ldx #$04 //#$05 for 5x5 tiles loop: ldy #$00 sta (colourmem),y ldy #$28 sta (colourmem),y ldy #$50 sta (colourmem),y ldy #$78 sta (colourmem),y //+one more row for 5x5 tiles inc colourmem bne !+ inc colourmem+1 !: dex bne loop ... Pseudo code for char colouring: ldx #$00 loop: ldy screenmem,x lda atttribtable,y sta colourmem,x inx bne loop ... Change the example code the way you need it (65-72). Read [[base:rant4|Cadavers "Rant 4"]] to see how tile maps are structured in memory. Most important is "Mapx". This has to be changed according to the acutal map width. In this case: map width = 10 tiles = 40 chars = one screen wide. /*------------------------------------------------------- Decoding 4x4 tile based map Full screen by A. Volkers, 2011 Load your graphics data to the following addresses: charset: $2000 tiles: $3000 map: $3800 attributes: $3900 respectively change the code... -> KickAssembler -------------------------------------------------------*/ .pc = $1000 .const tiledatamem = 48 //hi-byte start address tile data (=$3000) .var mapdata = $02 //16bit address map data for decoder .var tiledata = $04 //16bit address tile data for decoder .var tileX = $fc //tile columns .var tileY = $fd //tile rows .var NumberTilesX = $fe //number of tiles from left to right .var NumberTilesY = $ff //number of tiles from top to bottom .var map = $20 //16bit address map data for main program .var attribs = $22 //16bit address attributes (=colour) .var screen = $24 //16bit screen address .var mapX = $26 //map width lda #$0a //in this case: map width=number of tiles left-right sta mapX //change for required map width... lda #$00 sta map lda #$38 sta map+1 //map: $3800 lda #$00 sta attribs lda #$39 sta attribs+1 //attributes: $3900 lda #$00 sta screen lda #$04 sta screen+1 //screen: $0400 lda #$09 //set colours sta $d021 lda #$00 sta $d020 lda #$0b sta $d022 lda #$01 sta $d023 lda #$18 sta $d018 //screen mem= $0400, char mem= $2000 lda #$d8 sta $d016 //multicolour jsr decoder lda #$08 //black ldx #$00 //use required code here !: sta $d800,x //to colour the screen sta $d900,x sta $da00,x sta $db00,x inx bne !- jmp* decoder:lda map sta mapdata lda map+1 sta mapdata+1 //set actual map pointer lda #$04 //4 rows per tile sta tileY lda #$03 //4 columns per tile sta tileX lda #$0a //number of tiles left-right sta NumberTilesX //#$08 in case of 5x5 tiles lda #$05 //number of tiles top-bottom sta NumberTilesY //=20 screen rows lda screen //prepare for printing sta printchar+1 lda screen+1 sta printchar+2 readmap:ldy #$00 lda (mapdata),y //read actual tile number from map data and #$0f //calculate tile address asl //use lo-/hi-byte-tables for 5x5 tiles instead asl asl asl sta tiledata //lo-byte tile data lda (mapdata),y and #$f0 lsr lsr lsr lsr clc adc #tiledatamem sta tiledata+1 //hi-byte tile data ldx #$03 //4 columns, #$04 for 5x5 tiles ldy tileX readchar:lda (tiledata),y //read actual char from tile data printchar:sta $ffff,x //print actual char dey dex bpl readchar inc mapdata //read next tile from map bne !+ inc mapdata+1 !: lda printchar+1 //add four columns clc //to print next tile adc #$04 sta printchar+1 bcc !+ inc printchar+2 !: dec NumberTilesX //all tiles left-right done? bne readmap lda #$0a //reset number of tiles left-right sta NumberTilesX lda tileX //next tile row clc adc #$04 sta tileX lda mapdata //reset map pointer sec sbc #$0a sta mapdata bcs !+ dec mapdata+1 !: dec tileY //all tile rows done? bne readmap lda #$04 //reset tileY sta tileY lda #$03 //reset tileX sta tileX lda mapdata //next map row clc adc mapX sta mapdata bcc !+ inc mapdata+1 !: dec NumberTilesY //all tiles top-bottom done? beq !+ jmp readmap !: rts