static int init(void) { LOG_DEBUG(2,"Initialising NDS audio (ARM9 side)\n"); flush_event = event_new(); flush_event->dispatch = flush_frame; memset(buf, 0x80, sizeof(buf)); writing_buf = 0; frame_base = buf; wrptr = buf; frame_cycle_base = current_cycle; frame_cycle = 0; flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES; event_queue(&MACHINE_EVENT_LIST, flush_event); lastsample = 0x80; //0; /* handshake with ARM7 to pass sound buffer address */ REG_IPC_FIFO_CR = (1 << 3) | (1 << 15); /* enable FIFO, clear sendq */ REG_IPC_SYNC = (14 << 8); while ((REG_IPC_SYNC & 15) != 14); REG_IPC_FIFO_TX = (uint32_t)buf; REG_IPC_SYNC = (1 << 14) | (0 << 8); /* IRQ on sync */ irqEnable(IRQ_IPC_SYNC); /* now wait for ARM7 to be playing frame 1 */ while ((REG_IPC_SYNC & 1) != 1) { swiIntrWait(1, IRQ_IPC_SYNC); } return 0; }
static u32 fifo_waitBlock() { u32 block; do { block = fifo_allocBlock(); if (block == FIFO_BUFFER_TERMINATE) { REG_IPC_FIFO_CR |= IPC_FIFO_SEND_IRQ; REG_IME = 1; swiIntrWait(0,IRQ_FIFO_EMPTY); REG_IME = 0; } } while(block == FIFO_BUFFER_TERMINATE); return block; }
void sleepMode(u32 value32, void* userdata) {iprintf("sleep mode engaged\n");for(;;); fifoSendValue32(FIFO_USER_03, 1); // turn shit off u32 powerstate = *(vu32*)0x04000304; *(vu32*)0x04000304 = (powerstate & 0x8001); swiIntrWait(1, IRQ_FIFO_NOT_EMPTY); iprintf("done sleeping\n"); // turn shit back on *(vu32*)0x04000304 = powerstate; fifoSendValue32(FIFO_USER_03, 1); while (!fifoCheckValue32(FIFO_USER_03)); }
static void flush_frame(void) { uint8_t *fill_to = frame_base + FRAME_SIZE; while (wrptr < fill_to) *(wrptr++) = lastsample; DC_FlushRange(frame_base, FRAME_SIZE); frame_cycle_base += FRAME_CYCLES; frame_cycle = 0; flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES; event_queue(&MACHINE_EVENT_LIST, flush_event); writing_buf ^= 1; frame_base = buf + (writing_buf * FRAME_SIZE); wrptr = frame_base; /* wait here */ if ((REG_IPC_SYNC & 1) == writing_buf) { swiIntrWait(1, IRQ_IPC_SYNC); } }
void neoSystem7Execute() { s32 cycles = 0; u32 i; while(1) { for(i = 0; i < Z80_TIMESLICE_PER_FRAME; i++) { cycles += Z80_CLOCKS_PER_TIMESLICE; cycles -= neoZ80Execute(cycles); neoSystem7ProcessCommands(); neoYM2610Process(); } swiIntrWait(1, IRQ_VCOUNT); neoAudioUpdate(); //neoYM2610StreamProcess(); NEOIPC->arm7Alive++; } }
int ARM7_MAIN(void) { readUserSettings(); // init irq irqInit(); initClockIRQ(); // init irq callback irqSet(IRQ_VCOUNT, IRQ_VCount); irqSet(IRQ_VBLANK, IRQ_VBlank); irqEnable(IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK); // init fifo system fifoInit(); // install fifo subsystems installWifiFIFO(); installSoundFIFO(); installSystemFIFO(); mmInstall(FIFO_MAXMOD); // init fifo callback for arm9 communication fifoSetDatamsgHandler(FIFO_USER_01, I_PollArm9Messages, 0); SetYtrigger(80); setPowerButtonCB(powerButtonCB); // Keep the ARM7 mostly idle while(!exitflag) { if(0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) exitflag = true; swiIntrWait(1, IRQ_FIFO_NOT_EMPTY | IRQ_VBLANK); } return 0; }
void _interruptController::waitForVerticalCount( bool skipIfAlreadyOccoured ){ swiIntrWait( !skipIfAlreadyOccoured , IRQ_VCOUNT ); }
void _interruptController::waitForVerticalBlank( bool skipIfAlreadyOccoured ){ swiIntrWait( !skipIfAlreadyOccoured , IRQ_VBLANK ); }
int main(void) { mmInitDefaultMem((mm_addr)soundbank_bin); //set video mode and map vram to the background videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE | DISPLAY_SPR_1D_LAYOUT | DISPLAY_SPR_ACTIVE); vramSetBankA(VRAM_A_MAIN_BG_0x06000000); vramSetBankB(VRAM_B_MAIN_SPRITE); //set video mode and map vram to the background videoSetModeSub(MODE_1_2D | DISPLAY_BG1_ACTIVE | DISPLAY_SPR_1D_LAYOUT | DISPLAY_SPR_ACTIVE); vramSetBankD(VRAM_D_MAIN_BG_0x06000000); vramSetBankE(VRAM_E_MAIN_SPRITE); lcdMainOnBottom(); #ifdef BBDEBUG consoleDemoInit(); #endif sound s; s.load_bank(0); sprites spr; machine m(&s); machine_view mv(&spr); #ifndef BBDEBUG thread_view tv; #endif cursor c(&m,&spr); pointer p(&spr); iprintf("%d\n",list::unit_test()); int frame=0; int x=0; int y=0; int tx=0; int ty=0; int dx=0; int dy=0; int touchedlast=0; int tempo=2; int bank=0; u8 flip=0; u8 flip_count=1; irqEnable( IRQ_VCOUNT ); while(1) { // wait until line 0 swiIntrWait( 0, IRQ_VCOUNT); u32 t=tempo; //t=t/(flip+1); //iprintf("%d\n",t); if (tempo==0 || frame%t==0) { m.run(); /* flip_count--; if (flip_count==0) { flip_count=4; if (flip) flip=0; else flip=1; }*/ } scanKeys(); frame++; touchPosition touch; touchRead(&touch); if (keysDown() & KEY_UP) m.slow_down_closest(c.get_cursor_addr()); if (keysDown() & KEY_DOWN) m.speed_up_closest(c.get_cursor_addr()); if (tempo<0) tempo=0; if (keysDown() & KEY_L) sound_check(m); if (keysDown() & KEY_LEFT) { bank--; s.load_bank(bank); } if (keysDown() & KEY_RIGHT) { bank++; s.load_bank(bank); } if(keysDown() & KEY_TOUCH) { tx=touch.px; ty=touch.py; if (!c.touch(tx,ty,&p)) { touchedlast=1; } } else if(keysHeld() & KEY_TOUCH) { if (!c.menu_shown() && !c.drag(touch.px+x,touch.py+y,(touch.px+x)/16,(touch.py+y)/16)) { if (touchedlast>0) touchedlast++; x+=tx-touch.px; y+=ty-touch.py; tx=touch.px; ty=touch.py; } } if (keysUp() & KEY_TOUCH) { if (touchedlast>0 && touchedlast<5) { int lx=(tx+x)/16; int ly=(ty+y)/16; c.set_pos(lx,ly,lx*16,ly*16); } touchedlast=0; } if (keysUp() & KEY_A) { for (u32 i=0; i<HEAP_SIZE; i++) { m.poke(i,rand()); } } c.update(x,y); if (c.menu_shown()) { dx=c.get_x()-128; dy=c.get_y()-82; if (dx!=x) x+=(dx-x)*0.1; if (dy!=y) y+=(dy-y)*0.1; } p.update(x,y,&m); REG_BG0HOFS = x; REG_BG0VOFS = y; spr.update(); mv.update(x,y,&m); s.update(); #ifndef BBDEBUG tv.update(&m); #endif BG_PALETTE_SUB[0]=13<<10; swiWaitForVBlank(); BG_PALETTE_SUB[0]=31; } return 0; }
//--------------------------------------------------------------------------------- int main(int argc, char ** argv) { //--------------------------------------------------------------------------------- readUserSettings(); irqInit(); initClockIRQ(); fifoInit(); SetYtrigger(80); #ifdef USE_WIFI installWifiFIFO(); #endif //installSoundFIFO(); installSystemFIFO(); //TIMER_CR(0) = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_1; vcount = 80; irqSet(IRQ_VBLANK, VblankHandler); irqSet(IRQ_VCOUNT, VcountHandler); irqSet(IRQ_HBLANK, hblank_handler); irqEnable(IRQ_VBLANK | IRQ_VCOUNT | IRQ_HBLANK); setPowerButtonCB(powerButtonCB); fifoSetDatamsgHandler(FIFO_9to7, fifo_DataHandler, 0); // irqSet(IRQ_LID, lid); // irqEnable(IRQ_LID); #ifdef IPC_IN_TIMER irqSet(IRQ_TIMER0, handle_ipc); TIMER_DATA(0) = TIMER_FREQ_256(20 * 60); TIMER_CR(0) = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_256; #endif #ifdef USE_WIFI #ifndef WIFI_ON_DEMAND wifi_go(); #endif #endif #ifdef USE_ADHOC IPC_Init() ; LWIFI_Init() ; #endif // Keep the ARM7 idle while (!exitflag) { //ARM7_PRINT("arm7 "); if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) { exitflag = true; } #ifdef USE_ADHOC LWIFI_IPC_UpdateNOIRQ() ; #endif if (do_mp3 != 0) { #ifdef USE_MP3 ds_enable_interrupts(0); if (helix_initialised == 0) { ARM7_PRINT("beginning helix init\n"); helix_init(); ARM7_PRINT("helix init done\n"); helix_initialised = 1; } char helix_argv1[100]; char helix_argv2[100]; memset(helix_argv1, 0, 100); memset(helix_argv2, 0, 100); strcpy(helix_argv1, "/jones.mp3"); // sprintf(helix_argv1, "/quake soundtrack/0%d-AudioTrack 0%d.mp3", mp3_track_no, mp3_track_no); // strcpy(helix_argv2, "/jones.pcm"); char *proper_helix_argv[3]; proper_helix_argv[0] = NULL; proper_helix_argv[1] = helix_argv1; // proper_helix_argv[1] = (char *)track_name; proper_helix_argv[2] = helix_argv2; ARM7_PRINT("Starting Helix...\n"); decoder_stopped = 0; ds_enable_interrupts(1); helix_main(3, proper_helix_argv); ds_enable_interrupts(0); decoder_stopped = 1; ARM7_PRINT("out of helix\n"); // ARM7_HALT(); send_mp3_stop_message(); ds_enable_interrupts(1); #endif } // if (REG_KEYXY & (1 << 7)) // { // while (quake_ipc_7to9->message == 0xffffffff); // // quake_ipc_7to9->message_type = kLidHasClosed; // quake_ipc_7to9->message = 0xffffffff; // // while (quake_ipc_7to9->message == 0xffffffff); // // ARM7_PRINT("ARM7: waiting...\n"); // while (REG_IPC_FIFO_CR&IPC_FIFO_RECV_EMPTY); // ARM7_PRINT("ARM7: disabling interrupts\n"); // // irqDisable(IRQ_HBLANK); // irqDisable(IRQ_VBLANK); // irqDisable(IRQ_VCOUNT); // //// irqEnable(IRQ_LID); // // powerOFF(POWER_SOUND); // // swiWaitForVBlank(); //wake up when the lid re-enables the interrupt // } if (arm7_initialised && ((hblanks & 0x3f) == 0)) { arm7_initialised = 1; //ARM7_PRINT("ping"); //while (quake_ipc_7to9->message == 0xffffffff); //quake_ipc_7to9->message_type = kPing; //quake_ipc_7to9->message = 0xffffffff; //while (quake_ipc_7to9->message == 0xffffffff); } // int total = 0; // for (int count = 0 ; count < 16; count++) // if (!is_channel_enabled(count)) // total++; // if (free_time == kFreeTime) // ARM7_PRINTF("%d channels free\n", total); // if (free_time == kFreeTime) // if (needs_defrag()) // { // ARM7_PRINT("NEEDS DEFRAG\n"); // defrag(&free_time); // } // swiWaitForVBlank(); #ifdef IPC_IN_MAIN_THREAD //handle_ipc(); #endif // if (arm7_initialised == true) // { //// temp_test(); // // arm7_initialised = false; // ARM7_PRINT("installing exception handler\n"); // install(); // register unsigned int sp asm ("13"); // ARM7_PRINT("done\nlet\'s try and crash it\n"); // /*ARM7_PRINT_NUMBER(sp);*/ // //// asm("LDR r12,=MyReg2\n" //// "STMIA r12,{r0-r15}\n" //// : //// : //// : "r12"); // //// ARM7_PRINT_NUMBER(MyReg2[12]); // //// for (int count = 0; count < 16; count++) //// ARM7_PRINT_NUMBER(MyReg2[count]); //// ARM7_PRINT("\n"); //// while(1); //// asm (".word 0xffffffff"); //// asm (".word 0x0"); // // //// Exception(); // //// asm (".word 0xe6000010"); // //// asm("LDR r12,=MyReg2\n" //// "STMIA r12,{r0-r15}\n" //// : //// : //// : "r12"); //// //// for (int count = 0; count < 8; count++) //// { //// ARM7_PRINT_NUMBER(MyReg[count + 8]); //// ARM7_PRINT_NUMBER(MyReg2[count + 8]); //// } // // //// asm ("mcr 15,0,r0,c0,c0,0"); //// asm ("bkpt"); //// *(int *)0 = 0; //// asm ("b debugger_hit"); //// debugger_hit(); //// debugger_handle_breakpoint(0,0,0); // //// asm (".word 0xe6000010"); //// asm (".short 0xe801"); // ARM7_PRINT("shouldn\'t make it here\n"); // ARM7_PRINT_NUMBER(ProperCPSR); // while(1); // } swiIntrWait(1, 1); } }
//--------------------------------------------------------------------------------- int loadNDS(int socket, u32 remote) { //--------------------------------------------------------------------------------- int len; int i=0; ioctl(socket,FIONBIO,&i); len = recvall(socket,__NDSHeader,512,0); if (len != 512) { kprintf("Error reading header.\n"); return 1; } int arm7dest = __NDSHeader->arm7destination; int arm7size = __NDSHeader->arm7binarySize; int arm9dest = __NDSHeader->arm9destination; int arm9size = __NDSHeader->arm9binarySize; volatile int response = 0; if (arm9dest + arm9size > (int)_start) response = 1; if (arm7dest >= 0x02000000 && arm7dest < 0x03000000 && arm7dest + arm7size > (int)_start) response = 2; send(socket,(int *)&response,sizeof(response),0); if(response) return 1; kprintf("Reading arm7 binary: "); if (progressRead(socket,(char *)memUncached((void*)0x02000000),arm7size)) { kprintf("\nReceive error.\n"); return 1; } fifoSendValue32(FIFO_USER_01,1); while(!fifoCheckValue32(FIFO_USER_01)) { swiIntrWait(1,IRQ_FIFO_NOT_EMPTY); } fifoGetValue32(FIFO_USER_01); kprintf("Reading arm9 binary: "); if(progressRead(socket,(char *)arm9dest,arm9size)) { kprintf("\nReceive error.\n"); return 1; } volatile int cmdlen=0; char *cmdline; if (arm9size != 0){ cmdline = (char*)(arm9dest+arm9size); } else { cmdline = (char*)(arm7dest+arm7size); } len = recvall(socket,(char*)&cmdlen,4,0); if (cmdlen) { len = recvall(socket,cmdline,cmdlen,0); __system_argv->argvMagic = ARGV_MAGIC; __system_argv->commandLine = cmdline; __system_argv->length = cmdlen; __system_argv->host = remote; } Wifi_DisableWifi(); DC_FlushAll(); REG_IPC_SYNC = 0; fifoSendValue32(FIFO_USER_01,2); fifoSendValue32(FIFO_USER_01,__NDSHeader->arm9executeAddress); irqDisable(IRQ_ALL); REG_IME = 0; //clear out ARM9 DMA channels for (i=0; i<4; i++) { DMA_CR(i) = 0; DMA_SRC(i) = 0; DMA_DEST(i) = 0; TIMER_CR(i) = 0; TIMER_DATA(i) = 0; } u16 *mainregs = (u16*)0x04000000; u16 *subregs = (u16*)0x04001000; for (i=0; i<43; i++) { mainregs[i] = 0; subregs[i] = 0; } REG_DISPSTAT = 0; dmaFillWords(0, BG_PALETTE, (2*1024)); VRAM_A_CR = 0x80; dmaFillWords(0, VRAM, 128*1024); VRAM_A_CR = 0; VRAM_B_CR = 0; // Don't mess with the ARM7's VRAM // VRAM_C_CR = 0; VRAM_D_CR = 0; VRAM_E_CR = 0; VRAM_F_CR = 0; VRAM_G_CR = 0; VRAM_H_CR = 0; VRAM_I_CR = 0; REG_POWERCNT = 0x820F; //set shared ram to ARM7 WRAM_CR = 0x03; // Return to passme loop *((vu32*)0x02FFFE04) = (u32)0xE59FF018; // ldr pc, 0x02FFFE24 *((vu32*)0x02FFFE24) = (u32)0x02FFFE04; // Set ARM9 Loop address REG_IPC_SYNC = 0x500; arm9Reset(); while(1); }
int App_Test::start() { int code_out = 0; this->model_animated[ 0] = (u8 *)heavy_walk_01_bin; this->model_animated[ 1] = (u8 *)heavy_walk_02_bin; this->model_animated[ 2] = (u8 *)heavy_walk_03_bin; this->model_animated[ 3] = (u8 *)heavy_walk_04_bin; this->model_animated[ 4] = (u8 *)heavy_walk_05_bin; this->model_animated[ 5] = (u8 *)heavy_walk_06_bin; this->model_animated[ 6] = (u8 *)heavy_walk_07_bin; this->model_animated[ 7] = (u8 *)heavy_walk_08_bin; this->model_animated[ 8] = (u8 *)heavy_walk_09_bin; this->model_animated[ 9] = (u8 *)heavy_walk_10_bin; this->model_animated[10] = (u8 *)heavy_walk_11_bin; this->model_animated[11] = (u8 *)heavy_walk_12_bin; this->model_animated[12] = (u8 *)heavy_walk_13_bin; this->model_animated[13] = (u8 *)heavy_walk_14_bin; this->model_animated[14] = (u8 *)heavy_walk_15_bin; this->model_animated[15] = (u8 *)heavy_walk_16_bin; this->model_animated[16] = (u8 *)heavy_walk_17_bin; this->model_animated[17] = (u8 *)heavy_walk_18_bin; this->model_animated[18] = (u8 *)heavy_walk_19_bin; this->model_animated[19] = (u8 *)heavy_walk_20_bin; this->model_animated[20] = (u8 *)heavy_walk_21_bin; this->model_animated[21] = (u8 *)heavy_walk_22_bin; this->model_animated[22] = (u8 *)heavy_walk_23_bin; this->model_animated[23] = (u8 *)heavy_walk_24_bin; this->model_animated[24] = (u8 *)heavy_walk_25_bin; this->model_animated[25] = (u8 *)heavy_walk_26_bin; this->model_animated[26] = (u8 *)heavy_walk_27_bin; this->model_animated[27] = (u8 *)heavy_walk_28_bin; this->model_animated[28] = (u8 *)heavy_walk_29_bin; this->model_animated[29] = (u8 *)heavy_walk_30_bin; this->model_animated[30] = (u8 *)heavy_walk_31_bin; this->model_animated[31] = (u8 *)heavy_walk_32_bin; this->model_animated[32] = (u8 *)heavy_walk_33_bin; this->model_animated[33] = (u8 *)heavy_walk_34_bin; this->model_animated[34] = (u8 *)heavy_walk_35_bin; this->model_animated[35] = (u8 *)heavy_walk_36_bin; this->model_animated[36] = (u8 *)heavy_walk_37_bin; this->model_animated[37] = (u8 *)heavy_walk_38_bin; this->model_animated[38] = (u8 *)heavy_walk_39_bin; this->model_animated[39] = (u8 *)heavy_walk_40_bin; //Animations variables this->frame = 0; this->max_frame = 40; //Debug variables for animations int32 test_time = 0; this->xrot = 0.0f; this->yrot = 0.0f; this->zrot = 0.0f; this->p_mgr_display->setup_screen(); this->target.set_vec_ox(0); this->target.set_vec_oy(0); this->target.set_vec_oz(0); this->camera.setLookAt(CAMERA_MODE_TARGET,&(this->target)); this->camera.computeLookAt(); this->camera.dist_from_target = floattof32(23); this->p_mgr_display->set_camera(&(this->camera)); this->p_mgr_display->init(); this->load_Texture(); this->app_running = 1; this->p_mgr_system->reset_timer(); this->animation_pause = 1; glSetToonTableRange( 0, 8, RGB15(8,8,8) ); glSetToonTableRange( 8, 10, RGB15(12,12,12) ); glSetToonTableRange( 10, 13, RGB15(16,16,16) ); glSetToonTableRange( 13, 31, RGB15(31,31,31) ); //glEnable(GL_TOON_HIGHLIGHT); while(this->app_running) { this->process_inputs(); //printf("%d\n",this->p_mgr_system->last_millisec); //this->camera.setStep(this->p_mgr_system->last_millisec); // TODO : init and use millisec pointer within Model_Camera this->camera.setStep(17); // TODO : init and use millisec pointer within Model_Camera //Animations step calculation //this->frame += mulf32(this->frame_speed,this->p_mgr_system->last_millisec); if (!this->animation_pause) this->frame+= test_time; else this->frame=0; if (this->frame >= this->max_frame) this->frame = this->frame - this->max_frame; this->model_selected = this->model_animated[this->frame]; //Start Display this->p_mgr_display->begin_3D(); this->display_Model(); this->p_mgr_display->end_3D(); this->p_mgr_display->flush_display(); //End Display iprintf("\x1b[2J"); iprintf("\x1b[1;0Hframe = %d\n",this->frame); iprintf("\x1b[2;0Htest_timer = %d\n",timerElapsed(0)); iprintf("\x1b[3;0Htest_ms = %d\n",test_time); swiIntrWait(IRQ_TIMER0,1); iprintf("\x1b[5;0H Timer ok\n"); test_time = this->p_mgr_system->last_millisec; this->p_mgr_system->reset_timer(); // printf("dst_from_target = %f\n",f32tofloat(this->camera.dist_from_target)); swiWaitForVBlank(); } return code_out; }
/********************************************************************************** * main * * Program Entry Point **********************************************************************************/ int main( void ) { //--------------------------------------------------------------------------------- //---------------------------------------------------------------- // print out some stuff //---------------------------------------------------------------- consoleDemoInit(); iprintf( "\n Maxmod Streaming Example \n"); //---------------------------------------------------------------- // initialize maxmod without any soundbank (unusual setup) //---------------------------------------------------------------- mm_ds_system sys; sys.mod_count = 0; sys.samp_count = 0; sys.mem_bank = 0; sys.fifo_channel = FIFO_MAXMOD; mmInit( &sys ); //---------------------------------------------------------------- // open stream //---------------------------------------------------------------- mm_stream mystream; mystream.sampling_rate = 25000; // sampling rate = 25khz mystream.buffer_length = 1200; // buffer length = 1200 samples mystream.callback = on_stream_request; // set callback function mystream.format = MM_STREAM_16BIT_STEREO; // format = stereo 16-bit mystream.timer = MM_TIMER0; // use hardware timer 0 mystream.manual = true; // use manual filling mmStreamOpen( &mystream ); //---------------------------------------------------------------- // when using 'automatic' filling, your callback will be triggered // every time half of the wave buffer is processed. // // so: // 25000 (rate) // ----- = ~21 Hz for a full pass, and ~42hz for half pass // 1200 (length) //---------------------------------------------------------------- // with 'manual' filling, you must call mmStreamUpdate // periodically (and often enough to avoid buffer underruns) //---------------------------------------------------------------- SetYtrigger( 0 ); irqEnable( IRQ_VCOUNT ); while( 1 ) { // wait until line 0 swiIntrWait( 0, IRQ_VCOUNT); // update stream mmStreamUpdate(); // restore backdrop (some lines were drawn with another colour to show cpu usage) BG_PALETTE_SUB[0] = bg_colour; // wait until next frame swiWaitForVBlank(); // set backdrop to show cpu usage BG_PALETTE_SUB[0] = cpu_colour; } return 0; }