void BootDsGbaARM9() { REG_IME = 0; ResetVideo(); // This works the same way as PassMe. Arm9 will enter an endless loop and // Arm7 will jump to the beginning of gba cart. A loader on the cart will // copy everything to ram, change the arm9 loop address to point at the // new arm9 binary, and then finally jump to the new arm7 binary. REG_EXMEMCNT |= 0x8080; // ARM7 has access to GBA cart *((vu32*)0x027FFE04) = (u32)0xE59FF018; // ldr pc, 0x027FFE24 *((vu32*)0x027FFE24) = (u32)0x027FFE04; // Set ARM9 Loop address // notify arm7 IPC->mailData = 1; swiSoftReset(); }
void bsp_reset(void) { swiSoftReset(); }
int runNds (const void* loader, u32 loaderSize, u32 cluster, bool initDisc, bool dldiPatchNds, int argc, const char** argv) { char* argStart; u16* argData; u16 argTempVal = 0; int argSize; const char* argChar; irqDisable(IRQ_ALL); // Direct CPU access to VRAM bank C VRAM_C_CR = VRAM_ENABLE | VRAM_C_LCD; // Load the loader/patcher into the correct address vramcpy (LCDC_BANK_C, loader, loaderSize); // Set the parameters for the loader // STORED_FILE_CLUSTER = cluster; writeAddr ((data_t*) LCDC_BANK_C, STORED_FILE_CLUSTER_OFFSET, cluster); // INIT_DISC = initDisc; writeAddr ((data_t*) LCDC_BANK_C, INIT_DISC_OFFSET, initDisc); // WANT_TO_PATCH_DLDI = dldiPatchNds; writeAddr ((data_t*) LCDC_BANK_C, WANT_TO_PATCH_DLDI_OFFSET, dldiPatchNds); // Give arguments to loader argStart = (char*)LCDC_BANK_C + readAddr((data_t*)LCDC_BANK_C, ARG_START_OFFSET); argStart = (char*)(((int)argStart + 3) & ~3); // Align to word argData = (u16*)argStart; argSize = 0; for (; argc > 0 && *argv; ++argv, --argc) { for (argChar = *argv; *argChar != 0; ++argChar, ++argSize) { if (argSize & 1) { argTempVal |= (*argChar) << 8; *argData = argTempVal; ++argData; } else { argTempVal = *argChar; } } if (argSize & 1) { *argData = argTempVal; ++argData; } argTempVal = 0; ++argSize; } *argData = argTempVal; writeAddr ((data_t*) LCDC_BANK_C, ARG_START_OFFSET, (addr_t)argStart - (addr_t)LCDC_BANK_C); writeAddr ((data_t*) LCDC_BANK_C, ARG_SIZE_OFFSET, argSize); // Patch the loader with a DLDI for the card if (!dldiPatchLoader ((data_t*)LCDC_BANK_C, loaderSize, initDisc)) { return 3; } irqDisable(IRQ_ALL); // Give the VRAM to the ARM7 VRAM_C_CR = VRAM_ENABLE | VRAM_C_ARM7_0x06000000; // Reset into a passme loop REG_EXMEMCNT |= ARM7_OWNS_ROM | ARM7_OWNS_CARD; *((vu32*)0x027FFFFC) = 0; *((vu32*)0x027FFE04) = (u32)0xE59FF018; *((vu32*)0x027FFE24) = (u32)0x027FFE04; swiSoftReset(); return true; }
static void fifoInternalRecvInterrupt() { REG_IE &= ~IRQ_FIFO_NOT_EMPTY; REG_IME=1; u32 data, block=FIFO_BUFFER_TERMINATE; while( !(REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY) ) { REG_IME=0; block=fifo_allocBlock(); if (block != FIFO_BUFFER_TERMINATE ) { FIFO_BUFFER_DATA(block)=REG_IPC_FIFO_RX; fifo_queueBlock(&fifo_receive_queue,block,block); } REG_IME=1; } REG_IME=0; REG_IE |= IRQ_FIFO_NOT_EMPTY; if (!processing && fifo_receive_queue.head != FIFO_BUFFER_TERMINATE) { processing = 1; REG_IME=1; do { block = fifo_receive_queue.head; data = FIFO_BUFFER_DATA(block); u32 channel = FIFO_UNPACK_CHANNEL(data); if ( (data & (FIFO_ADDRESSBIT | FIFO_IMMEDIATEBIT)) == (FIFO_ADDRESSBIT | FIFO_IMMEDIATEBIT) ) { if ((data & FIFO_ADDRESSDATA_MASK) == 0x4000c ) { REG_IPC_SYNC = 0x100; while((REG_IPC_SYNC&0x0f) != 1); REG_IPC_SYNC = 0; swiSoftReset(); } } else if (FIFO_IS_ADDRESS(data)) { volatile void * address = FIFO_UNPACK_ADDRESS(data); REG_IME=0; fifo_receive_queue.head = FIFO_BUFFER_GETNEXT(block); if (fifo_address_func[channel]) { fifo_freeBlock(block); REG_IME=1; fifo_address_func[channel]( (void*)address, fifo_address_data[channel] ); } else { FIFO_BUFFER_DATA(block)=(u32)address; fifo_queueBlock(&fifo_address_queue[channel],block,block); } REG_IME=1; } else if(FIFO_IS_VALUE32(data)) { u32 value32; if (FIFO_UNPACK_VALUE32_NEEDEXTRA(data)) { int next = FIFO_BUFFER_GETNEXT(block); if (next==FIFO_BUFFER_TERMINATE) break; fifo_freeBlock(block); block = next; value32 = FIFO_BUFFER_DATA(block); } else { value32 = FIFO_UNPACK_VALUE32_NOEXTRA(data); } REG_IME=0; fifo_receive_queue.head = FIFO_BUFFER_GETNEXT(block); if (fifo_value32_func[channel]) { fifo_freeBlock(block); REG_IME=1; fifo_value32_func[channel]( value32, fifo_value32_data[channel] ); } else { FIFO_BUFFER_DATA(block)=value32; fifo_queueBlock(&fifo_value32_queue[channel],block,block); } REG_IME=1; } else if(FIFO_IS_DATA(data)) { int n_bytes = FIFO_UNPACK_DATALENGTH(data); int n_words = (n_bytes+3)>>2; int count=0; int end=block; while(count<n_words && FIFO_BUFFER_GETNEXT(end)!=FIFO_BUFFER_TERMINATE){ end = FIFO_BUFFER_GETNEXT(end); count++; } if (count!=n_words) break; REG_IME=0; fifo_receive_queue.head = FIFO_BUFFER_GETNEXT(end); int tmp=FIFO_BUFFER_GETNEXT(block); fifo_freeBlock(block); FIFO_BUFFER_SETCONTROL(tmp, FIFO_BUFFER_GETNEXT(tmp), FIFO_BUFFERCONTROL_DATASTART, n_bytes); fifo_queueBlock(&fifo_data_queue[channel],tmp,end); if(fifo_datamsg_func[channel]) { block = fifo_data_queue[channel].head; REG_IME=1; fifo_datamsg_func[channel](n_bytes, fifo_datamsg_data[channel]); if (block == fifo_data_queue[channel].head) fifoGetDatamsg(channel,0,0); } REG_IME=1; } else { fifo_receive_queue.head = FIFO_BUFFER_GETNEXT(block); fifo_freeBlock(block); } } while( fifo_receive_queue.head != FIFO_BUFFER_TERMINATE);
void gamescreen() { // set the mode for 2 text layers and two extended background layers videoSetMode(MODE_5_2D | //DISPLAY_BG1_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D_LAYOUT ); // set the first bank as background memory and the third as sub background memory // B and D are not used (if you want a bitmap greater than 256x256 you will need more // memory so another vram bank must be used and mapped consecutivly vramSetMainBanks(VRAM_A_MAIN_BG_0x6000000, VRAM_B_MAIN_SPRITE, //VRAM_B_MAIN_BG_0x6020000, VRAM_C_SUB_BG, VRAM_D_MAIN_BG_0x6020000); // set up our bitmap background BG3_CR = BG_BMP8_512x256 | BG_WRAP_ON| BG_BMP_BASE(0); //BG2_CR = BG_BMP8_256x256 | BG_BMP_BASE(8); BG1_CR = BG_32x32 | BG_TILE_BASE(0) | BG_MAP_BASE(8) | BG_256_COLOR; // these are rotation backgrounds so you must set the rotation attributes: // these are fixed point numbers with the low 8 bits the fractional part // this basicaly gives it a 1:1 translation in x and y so you get a nice flat bitmap BG3_XDX = 1 << 8; BG3_XDY = 0; BG3_YDX = 0; BG3_YDY = 1 << 8; BG2_XDX = 1 << 8; BG2_XDY = 0; BG2_YDX = 0; BG2_YDY = 1 << 8; //our bitmap looks a bit better if we center it so scroll down (256 - 192) / 2 BG3_CX = 0; BG3_CY = 0; BG2_CX = 0; BG2_CY = 0; for(int i = 0; i < 512*256; i++) BG_GFX[i] = ((u16*)topscreen_img_bin)[i]; for(int i = 0; i < 256; ++i) BG_PALETTE[i] = ((u16*)topscreen_pal_bin)[i]; //for(int i = 0; i < 256; ++i) //BG_PALETTE[i] = ((u16*)numbers_pal_bin)[i]; x = 0; y = 0; px = 128-32; py = 103; oldx = x; oldy = y; drag = false; touch_down = touchReadXY(); initSprites(); for(int i=0;i<256*256;i++) { SPRITE_GFX[i] = i % 256 | ((i % 256) << 8); } //for(int i = 0; i < 8*8*256/2; ++i) // ((u16*)BG_TILE_RAM(0))[i] = ((u16*)numbers_img_bin)[i]; //for(int i = 0; i < 32*32; ++i) //((u16*)BG_MAP_RAM(8))[i] = i%256; /* for(int y=0;y<64; ++y) for(int x=0;x<32; ++x) { SPRITE_GFX[y*64+x] = ((u16*)sprite_img_bin)[y*32+x]; }*/ const u8* frames[16]; frames[0] = walk_frame00_img_bin; frames[1] = walk_frame01_img_bin; frames[2] = walk_frame02_img_bin; frames[3] = walk_frame03_img_bin; frames[4] = walk_frame04_img_bin; frames[5] = walk_frame05_img_bin; frames[6] = walk_frame06_img_bin; frames[7] = walk_frame07_img_bin; frames[8] = walk_frame08_img_bin; frames[9] = walk_frame09_img_bin; frames[10] = walk_frame10_img_bin; frames[11] = walk_frame11_img_bin; frames[12] = walk_frame12_img_bin; frames[13] = walk_frame13_img_bin; frames[14] = walk_frame14_img_bin; frames[15] = walk_frame15_img_bin; const u8* pal_frames[16]; pal_frames[0] = walk_frame00_pal_bin; pal_frames[1] = walk_frame01_pal_bin; pal_frames[2] = walk_frame02_pal_bin; pal_frames[3] = walk_frame03_pal_bin; pal_frames[4] = walk_frame04_pal_bin; pal_frames[5] = walk_frame05_pal_bin; pal_frames[6] = walk_frame06_pal_bin; pal_frames[7] = walk_frame07_pal_bin; pal_frames[8] = walk_frame08_pal_bin; pal_frames[9] = walk_frame09_pal_bin; pal_frames[10] = walk_frame10_pal_bin; pal_frames[11] = walk_frame11_pal_bin; pal_frames[12] = walk_frame12_pal_bin; pal_frames[13] = walk_frame13_pal_bin; pal_frames[14] = walk_frame14_pal_bin; pal_frames[15] = walk_frame15_pal_bin; for(int i=0;i<64*32; ++i) SPRITE_GFX[i] = ((u16*)sprite_img_bin)[i]; for(int i=0;i<32*32/2; ++i) SPRITE_GFX[i+64*32] = ((u16*)use_icon_img_bin)[i]; for(int i=0;i<64*32; ++i) SPRITE_GFX[i+ (64*32) + (32*16)] = ((u16*)smalldoor_img_bin)[i]; for(int i=0;i<64*32; ++i) SPRITE_GFX[i] = ((u16*)walk_frame00_img_bin)[i]; for(int i = 0; i < 256; ++i) SPRITE_PALETTE[i] = ((u16*)walk_frame00_pal_bin)[i]; sprites[0].attribute[0] = ATTR0_SQUARE | ATTR0_TYPE_BLENDED | ATTR0_BMP | px; sprites[0].attribute[1] = ATTR1_SIZE_64 | py | ATTR1_FLIP_Y; sprites[0].attribute[2] = ATTR2_ALPHA(3); sprites[1].attribute[0] = ATTR0_SQUARE | ATTR0_COLOR_256 | (192-32-8) | ATTR0_DISABLED; sprites[1].attribute[1] = ATTR1_SIZE_32 | (256-32-8); sprites[1].attribute[2] = 64*2;//64*64;//64*32; sprites[2].attribute[0] = ATTR0_SQUARE | ATTR0_COLOR_256 | 90-6; sprites[2].attribute[1] = ATTR1_SIZE_64 | 200+16+2; sprites[2].attribute[2] = 64*2+32; int frame_index = 0; int sx = 0; //int sy = 0; bool left = true;; if (subscreen_mode == PDA) init_pda(); else init_doorminigame(); while(1) { swiWaitForVBlank(); frame_index += 1; frame_index = frame_index % 80; //SPRITE_GFX[i] = ((u16*)numbers_img_bin)[i]; // read the button states scanKeys(); touch = touchReadXY(); pressed = keysDown(); // buttons pressed this loop held = keysHeld(); // buttons currently held if (subscreen_mode != DIALOG) { sprites[0].attribute[0] = ATTR0_SQUARE | ATTR0_TYPE_BLENDED | ATTR0_COLOR_256 | mod(103,512); sprites[0].attribute[1] = ATTR1_SIZE_64 | mod(128-32,512) | (left ? 0: ATTR1_FLIP_X); sprites[0].attribute[2] = ATTR2_ALPHA(3); sprites[2].attribute[0] = ATTR0_SQUARE | ATTR0_TYPE_BLENDED | ATTR0_COLOR_256 | mod(90-6, 512); sprites[2].attribute[1] = ATTR1_SIZE_64 | mod((200+16+2 - px + 128-32 + door_pos/4),512); sprites[2].attribute[2] = ATTR2_ALPHA(1) | 64*2+32; } else { sprites[0].attribute[0] |= ATTR0_DISABLED; sprites[1].attribute[0] |= ATTR0_DISABLED; sprites[2].attribute[0] |= ATTR0_DISABLED; } if ((held & KEY_L) && (held & KEY_R)) swiSoftReset(); if ((pressed & KEY_LEFT) || (pressed & KEY_RIGHT)) { frame_index = 0; } if (held & KEY_LEFT) { left = true; px -= 1; sprites[0].attribute[1] = sprites[0].attribute[1] & ~ATTR1_FLIP_X; for(int i=0;i<64*32; ++i) SPRITE_GFX[i] = ((u16*)frames[frame_index/5])[i]; for(int i = 0; i < 256; ++i) SPRITE_PALETTE[i] = ((u16*)pal_frames[frame_index/5])[i]; } else if (held & KEY_RIGHT) { left = false; px += 1; sprites[0].attribute[1] = sprites[0].attribute[1] | ATTR1_FLIP_X; for(int i=0;i<64*32; ++i) SPRITE_GFX[i] = ((u16*)frames[frame_index/5])[i]; for(int i = 0; i < 256; ++i) SPRITE_PALETTE[i] = ((u16*)pal_frames[frame_index/5])[i]; } else { for(int i=0;i<64*32; ++i) SPRITE_GFX[i] = ((u16*)frames[0])[i]; for(int i = 0; i < 256; ++i) SPRITE_PALETTE[i] = ((u16*)pal_frames[0])[i]; } if (held & KEY_DOWN) py += 1; else if (held & KEY_UP) py -= 1; if ((px + 128) > 328-16 && (px + 128) < (328+35+16)) { sprites[1].attribute[0] &= ~ATTR0_DISABLED; //if (pressed & KEY_X) // { if (subscreen_mode == PDA) { init_doorminigame(); subscreen_mode = DOOR_MINIGAME; } else if (subscreen_mode == DOOR_MINIGAME) { init_pda(); subscreen_mode = PDA; } //} } else if ((px + 128) > 133-16 && (px + 128) < 133-16+32) { init_dialog(); subscreen_mode = DIALOG; } else { sprites[1].attribute[0] |= ATTR0_DISABLED; if (subscreen_mode == DOOR_MINIGAME) { init_pda(); subscreen_mode = PDA; } } sx = px; //sx += 1; if ((held & KEY_TOUCH) && drag) { x = oldx + (touch_down.px - touch.px); y = oldy + (touch_down.py - touch.py); } if (!(held & KEY_TOUCH)) drag = false; if (subscreen_mode != DIALOG) { BG3_CX = x*500 + sx<<8 ; BG3_CY = y*500 + (32<<8); } //2_CX = -x; //2_CY = -y; update_subscreen(); updateOAM(); } }