////////////////////////////////////////////////////////////////////// // sram_demo1 ARM9 Code - Based on an example shipped with NDSLIB. // Chris Double (chris.double@double.co.nz) ////////////////////////////////////////////////////////////////////// #include #include #include static char card_id[5] = { 0,0,0,0,0 }; static char sram_data[101] = { 0 }; static char copy_status[32] = { 0 }; void on_irq() { if(REG_IF & IRQ_VBLANK) { // Clear screen printf("\x1b[2J"); printf("\n\nReading and Writing GBA SRAM!\n\n"); printf("Using your flash cartridge\n"); printf("software you can load text data\n"); printf("into SRAM to test this program.\n"); printf("SRAM is the 'save game' area in\n"); printf("the cartridge.\n\n"); printf("Press:\n"); printf("'A' to display some SRAM data.\n"); printf("'B' to set SRAM to some text,\n"); printf("then press 'A' to display it.\n\n"); printf("Card ID = %s\n", card_id); printf("Copy Status:\n"); printf("%s\n", copy_status); printf("SRAM Data:\n"); printf("%s", sram_data); // Tell the DS we handled the VBLANK interrupt VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK; REG_IF |= IRQ_VBLANK; } else { // Ignore all other interrupts REG_IF = REG_IF; } } void InitInterruptHandler() { REG_IME = 0; IRQ_HANDLER = on_irq; REG_IE = IRQ_VBLANK; REG_IF = ~0; DISP_SR = DISP_VBLANK_IRQ; REG_IME = 1; } static void memcpy(char* dest, char const* src, int size) { while(size--) *dest++ = *src++; } static void memset(char* dest, char fill, int size) { while(size--) *dest++ = fill; } /* Return true if the card id is 'PASS' */ static int is_homebrew_cartridge() { return card_id[0] == 'P' && card_id[1] == 'A' && card_id[2] == 'S' && card_id[3] == 'S'; } int main(void) { powerON(POWER_ALL); videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE); vramSetBankA(VRAM_A_MAIN_BG); BG0_CR = BG_MAP_BASE(31); BG_PALETTE[255] = RGB15(31,31,31); lcdSwap(); /* Clear out our local copy of 1st 100 bytes of SRAM */ memset(sram_data, 0, sizeof(sram_data)); memset(copy_status, 0, sizeof(copy_status)); /* Enable the ARM9 to access the GBA cartridge memory area */ WAIT_CR &= ~0x80; /* Copy contents of the 4 character ROM identifier into a local variable. This should be 'PASS' for all homebrew ROM's. The identifier is located at 0x080000AC.*/ memcpy(card_id, (char*)0x080000AC, 4); /* Set up the vertical blank interrupt where we display our data */ InitInterruptHandler(); consoleInitDefault((u16*)SCREEN_BASE_BLOCK(31), (u16*)CHAR_BASE_BLOCK(0), 16); while(1) { int keys = ~REG_KEYINPUT; if(keys & KEY_A) { /* Copy from SRAM to our local variable to display */ memcpy(sram_data, (char*)SRAM, sizeof(sram_data) - 1); } if(keys & KEY_B) { /* Copy a string of text to SRAM if the cartridge has a homebrew ROM in it. */ const char text[] = "Hello from SRAM!"; const char error[] = "Not Homebrew! Copy failed."; const char success[] = "Copy succeeded."; if(is_homebrew_cartridge()) { memcpy((char*)SRAM, text, sizeof(text)); memcpy(copy_status, success, sizeof(success)); } else memcpy(copy_status, error, sizeof(error)); } swiWaitForVBlank(); } return 0; }