/* * asm1.c * program which demonstraes GBA assembly */ #include #include /* include the image we are using */ #include "background.h" /* the width and height of the screen */ #define WIDTH 240 #define HEIGHT 160 /* the three tile modes */ #define MODE0 0x00 #define MODE1 0x01 #define MODE2 0x02 /* enable bits for the four tile layers */ #define BG0_ENABLE 0x100 #define BG1_ENABLE 0x200 #define BG2_ENABLE 0x400 #define BG3_ENABLE 0x800 /* the control registers for the four tile layers */ volatile unsigned short* bg0_control = (volatile unsigned short*) 0x4000008; volatile unsigned short* bg1_control = (volatile unsigned short*) 0x400000a; volatile unsigned short* bg2_control = (volatile unsigned short*) 0x400000c; volatile unsigned short* bg3_control = (volatile unsigned short*) 0x400000e; /* palette is always 256 colors */ #define PALETTE_SIZE 256 /* flag for turning on DMA */ #define DMA_ENABLE 0x80000000 /* flags for the sizes to transfer, 16 or 32 bits */ #define DMA_16 0x00000000 #define DMA_32 0x04000000 /* pointer to the DMA source location */ volatile unsigned int* dma_source = (volatile unsigned int*) 0x40000D4; /* pointer to the DMA destination location */ volatile unsigned int* dma_destination = (volatile unsigned int*) 0x40000D8; /* pointer to the DMA count/control */ volatile unsigned int* dma_count = (volatile unsigned int*) 0x40000DC; /* copy data using DMA */ void memcpy16_dma(unsigned short* dest, unsigned short* source, int amount) { *dma_source = (unsigned int) source; *dma_destination = (unsigned int) dest; *dma_count = amount | DMA_16 | DMA_ENABLE; } /* the display control pointer points to the gba graphics register */ volatile unsigned long* display_control = (volatile unsigned long*) 0x4000000; /* the address of the color palette */ volatile unsigned short* bg_palette = (volatile unsigned short*) 0x5000000; /* return a pointer to one of the 4 character blocks (0-3) */ volatile unsigned short* char_block(unsigned long block) { /* they are each 16K big */ return (volatile unsigned short*) (0x6000000 + (block * 0x4000)); } /* return a pointer to one of the 32 screen blocks (0-31) */ volatile unsigned short* screen_block(unsigned long block) { /* they are each 2K big */ return (volatile unsigned short*) (0x6000000 + (block * 0x800)); } /* function to setup background 0 for this program */ void setup_background() { /* load the palette from the image into palette memory*/ memcpy16_dma((unsigned short*) bg_palette, (unsigned short*) background_palette, PALETTE_SIZE); /* load the image into char block 0 */ memcpy16_dma((unsigned short*) char_block(0), (unsigned short*) background_data, (background_width * background_height) / 2); /* bg0 is just all black so the pink does not show through! */ *bg0_control = 3 | /* priority, 0 is highest, 3 is lowest */ (0 << 2) | /* the char block the image data is stored in */ (0 << 6) | /* the mosaic flag */ (1 << 7) | /* color mode, 0 is 16 colors, 1 is 256 colors */ (16 << 8) | /* the screen block the tile data is stored in */ (1 << 13) | /* wrapping flag */ (0 << 14); /* bg size, 0 is 256x256 */ /* bg1 is our actual text background */ *bg1_control = 0 | /* priority, 0 is highest, 3 is lowest */ (0 << 2) | /* the char block the image data is stored in */ (0 << 6) | /* the mosaic flag */ (1 << 7) | /* color mode, 0 is 16 colors, 1 is 256 colors */ (24 << 8) | /* the screen block the tile data is stored in */ (1 << 13) | /* wrapping flag */ (0 << 14); /* bg size, 0 is 256x256 */ /* clear the tile map in screen block 16 to all black tile*/ volatile unsigned short* ptr = screen_block(16); for (int i = 0; i < 32 * 32; i++) { ptr[i] = 95; } /* clear the text map to be all blanks */ ptr = screen_block(24); for (int i = 0; i < 32 * 32; i++) { ptr[i] = 0; } } /* function to set text on the screen at a given location */ void set_text(char* str, int row, int col) { /* find the index in the texmap to draw to */ int index = row * 32 + col; /* the first 32 characters are missing from the map (controls etc.) */ int missing = 32; /* pointer to text map */ volatile unsigned short* ptr = screen_block(24); /* for each character */ while (*str) { /* place this character in the map */ ptr[index] = *str - missing; /* move onto the next character */ index++; str++; } } /* assembly implementation of the strlen function */ int mystrlen(char* string); /* the main function */ int main() { /* we set the mode to mode 0 with bg0 and bg1 on */ *display_control = MODE0 | BG0_ENABLE | BG1_ENABLE; /* setup the background 0 */ setup_background(); /* call assembly function */ int l = mystrlen("Hello"); /* print it */ char text[32]; sprintf(text, "Length of 'Hello' is %d", l); set_text(text, 0, 0); /* loop forever */ while (1) { } }