//! fills the surface with given color void CImage::fill(const SColor &color) { u32 c; switch ( Format ) { case ECF_A1R5G5B5: c = color.toA1R5G5B5(); c |= c << 16; break; case ECF_R5G6B5: c = video::A8R8G8B8toR5G6B5( color.color ); c |= c << 16; break; case ECF_A8R8G8B8: c = color.color; break; case ECF_R8G8B8: { u8 rgb[3]; CColorConverter::convert_A8R8G8B8toR8G8B8(&color, 1, rgb); const u32 size = getImageDataSizeInBytes(); for (u32 i=0; i<size; i+=3) { memcpy(Data+i, rgb, 3); } return; } break; } if (Format != ECF_A1R5G5B5 && Format != ECF_R5G6B5 && Format != ECF_A8R8G8B8) return; memset32( Data, c, getImageDataSizeInBytes() ); }
int *draw_selection_menu(char *title, int count, char *options[], const int *preselected) { // The caller has to make sure it does not exceed MAX_SELECTED_OPTIONS if (count > MAX_SELECTED_OPTIONS) { return NULL; } memset32(selected_options, 0, sizeof(selected_options)); int current = 0; int pos_x_text = 10 + 4 * SPACING_HORIZ; clear_screen(screen_top_left); draw_string(screen_top_left, title, 10, 10, COLOR_TITLE); draw_string(screen_top_left, "[ ]", 10, 40, COLOR_NEUTRAL); draw_string(screen_top_left, options[0], pos_x_text, 40, COLOR_SELECTED); int i; for (i = 1; i < count; i++) { draw_string(screen_top_left, "[ ]", 10, 40 + SPACING_VERT * i, COLOR_NEUTRAL); draw_string(screen_top_left, options[i], pos_x_text, 40 + SPACING_VERT * i, COLOR_NEUTRAL); } draw_string(screen_top_left, "Press START to confirm", 10, 40 + SPACING_VERT * (i + 2), COLOR_SELECTED); for (int i = 0; i < count; i++) { if (preselected[i]) { draw_character(screen_top_left, 'x', 10 + SPACING_HORIZ, 40 + SPACING_VERT * i, COLOR_NEUTRAL); selected_options[i] = 1; } } while (1) { uint16_t key = wait_key(); if (key == (key_released | key_up)) { draw_string(screen_top_left, options[current], pos_x_text, 40 + SPACING_VERT * current, COLOR_NEUTRAL); if (current <= 0) { current = count - 1; } else { current--; } draw_string(screen_top_left, options[current], pos_x_text, 40 + SPACING_VERT * current, COLOR_SELECTED); } else if (key == (key_released | key_down)) { draw_string(screen_top_left, options[current], pos_x_text, 40 + SPACING_VERT * current, COLOR_NEUTRAL); if (current >= count - 1) { current = 0; } else { current++; } draw_string(screen_top_left, options[current], pos_x_text, 40 + SPACING_VERT * current, COLOR_SELECTED); } else if (key == (key_released | key_a)) { if (selected_options[current]) { draw_character(screen_top_left, 'x', 10 + SPACING_HORIZ, 40 + SPACING_VERT * current, COLOR_BACKGROUND); selected_options[current] = 0; } else { draw_character(screen_top_left, 'x', 10 + SPACING_HORIZ, 40 + SPACING_VERT * current, COLOR_NEUTRAL); selected_options[current] = 1; } } else if (key == (key_released | key_start) || key == (key_released | key_b)) { return selected_options; } } }
void GCAMUpdateRegisters( void ) { u32 i; u32 *GInterface = (u32*)(GCAM_BASE); u32 *GInterfaceS = (u32*)(GCAM_SHADOW); sync_before_read( (void*)GCAM_BASE, 0x40 ); if( read32(GCAM_CONTROL) != 0xdeadbeef ) { if( read32( GCAM_CONTROL ) & (~3) ) { write32( GCAM_CONTROL, 0xdeadbeef ); sync_after_write( (void*)GCAM_BASE, 0x40 ); return; } /*write32( GCAM_SCONTROL, read32(GCAM_CONTROL) & 3 ); clear32( GCAM_SSTATUS, 0x14 ); write32( GCAM_CONTROL, 0xdeadbeef ); write32( GCAM_RETURN, 0xdeadbeef ); write32( GCAM_STATUS, 0xdeadbeef ); sync_after_write( (void*)GCAM_BASE, 0x40 );*/ for( i=0; i < 5; ++i ) { if( GInterface[i] != 0xdeadbeef ) { GInterfaceS[i] = GInterface[i]; GInterface[i] = 0xdeadbeef; } } switch( read32(GCAM_SCMD) >> 24 ) { case 0x00: { //dbgprintf("CARD:Warning unknown command!\n"); } break; case 0x50: { char *datain = (char*)P2C( read32(GCAM_SCMD_1) ); u32 lenin = read32(GCAM_SCMD_2); char *dataout = (char*)P2C( read32(GCAM_SCMD_3) ); u32 lenout = read32(GCAM_SCMD_4); #ifdef DEBUG_GCAM dbgprintf("SI:Transfer( %p, %u, %p, %u )\n", datain, lenin, dataout, lenout ); hexdump( datain, lenin ); #endif sync_before_read_align32(datain, lenin); switch( datain[0] ) { // dbgprintf("[%02X]", datain[0] ); case 0x00: { W32( (u32)dataout, 0x10110800 ); // dbgprintf("Reset(0x%p)\n", dataout ); } break; default: // CMD_DIRECT case 0x40: // CMD_ORIGIN case 0x41: // CMD_RECALIBRATE case 0x42: { memset( dataout, 0, lenout ); } break; } sync_after_write_align32(dataout, lenout); //hexdump( dataout, lenout ); //while( read32(GCAM_CONTROL) & 1 ) // clear32( GCAM_CONTROL, 1 ); //while( (read32(GCAM_SSTATUS) & 0x10) != 0x10 ) // set32( GCAM_SSTATUS, 0x10 ); } break; case 0x70: { char *datain = (char*)P2C( read32(GCAM_SCMD_1) ); char *dataout = (char*)P2C( read32(GCAM_SCMD_2) ); //dbgprintf("GC-AM:Command( %p, %u, %p, %u )\n", datain, 0x80, dataout, 0x80 ); sync_before_read_align32(datain, 0x80); memcpy( Bufi, datain, 0x80 ); GCAMCommand( Bufi, Buf ); if( FirstCMD == 0 ) { memset32( dataout, 0, 0x80 ); FirstCMD = 1; } else { memcpy( dataout, Bufo, 0x80 ); memcpy( Bufo, Buf, 0x80 ); } sync_after_write_align32(dataout, 0x80); //hexdump( dataout, 0x10 ); //while( read32(GCAM_CONTROL) & 1 ) // clear32( GCAM_CONTROL, 1 ); //while( (read32(GCAM_SSTATUS) & 0x10) != 0x10 ) // set32( GCAM_SSTATUS, 0x10 ); } break; default: { dbgprintf("Unhandled cmd:%02X\n", read32(GCAM_SCMD) ); Shutdown(); } break; } //to be 100% sure we dont ever read a still cached block in ppc write32( GCAM_CONTROL, 0xdeadbeef ); sync_after_write( (void*)GCAM_BASE, 0x40 ); } }
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ static int load_565rle_image(char *filename) { struct fb_info *info; int fd, err = 0; unsigned max, width, stride, line_pos = 0; unsigned short *data, *ptr; unsigned char *bits; signed count; info = registered_fb[0]; if (!info) { printk(KERN_ERR "%s: Can not access framebuffer\n", __func__); return -ENODEV; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_ERR "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; printk(KERN_ERR "%s: sys_lseek failed %s\n", __func__, filename); goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_ERR "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; printk(KERN_ERR "%s: sys_read failed %s\n", __func__, filename); goto err_logo_free_data; } width = fb_width(info); stride = fb_linewidth(info); max = width * fb_height(info); ptr = data; bits = (unsigned char *)(info->screen_base); while (count > 3) { int n = ptr[0]; if (n > max) break; max -= n; while (n > 0) { unsigned int j = (line_pos+n > width ? width-line_pos : n); if (fb_depth(info) == 2) { memset16(bits, ptr[1], j << 1); } else { /* Should probably add check for framebuffer * format here*/ unsigned int widepixel = ptr[1]; widepixel = (widepixel & 0xf800) << (19-11) | (widepixel & 0x07e0) << (10-5) | (widepixel & 0x001f) << (3-0) | 0xff000000; /* Set alpha channel*/ memset32(bits, widepixel, j << 2); } bits += j * fb_depth(info); line_pos += j; n -= j; if (line_pos == width) { bits += (stride-width) * fb_depth(info); line_pos = 0; } } ptr += 2; count -= 4; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
int load_888rle_image(char *filename) { struct fb_info *info; int fd, count, err = 0; unsigned max; unsigned short *data, *ptr; char *bits; printk(KERN_INFO "%s: load_888rle_image filename: %s\n", __func__, filename); info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { printk(KERN_WARNING "%s: Can not read data\n", __func__); err = -EIO; goto err_logo_free_data; } max = fb_width(info) * fb_height(info); ptr = data; bits = (char *)(info->screen_base); while (count > 3) { unsigned n = ptr[0]; if (n > max) break; if (info->var.bits_per_pixel/8 == 4) memset32(bits, ptr[1], n << 1); else memset16(bits, ptr[1], n << 1); bits += info->var.bits_per_pixel/8*n; max -= n; ptr += 2; count -= 4; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
/*! Translates 6502 instructions starting from \a instrPointer. \a instrPointer contains value of the 6502.PC register \a caller is a pointer to the branch instruction which initiated the translation */ inline void *NesCpuTranslator::process(u16 instrPointer, u8 *caller) { int count = 128; if (instrPointer < 0x4000) { count = 16; memset32(m_labels + m_lastRecompilationInRam, -m_translateCallerLabel.pos()-1, count * 4); m_lastRecompilationInRam = instrPointer; } // check if already translated if (m_labels[instrPointer] == m_translateCallerLabel) { Q_ASSERT(!m_checkAlertAfterInstruction); m_recPc = instrPointer; int page = nesCpuPageByAddr(instrPointer); int recompiledStart = m_pageTranslationOffset[page]; m_masm->setPcOffset(recompiledStart); // recompile here while (m_labels[m_recPc] == m_translateCallerLabel && nesCpuPageByAddr(m_recPc) == page && count > 0) { m_labels[m_recPc].unuse(); __ bind(&m_labels[m_recPc]); #if defined(ENABLE_DEBUGGING) __ mov(r0, Operand(currentPc())); __ bl(&m_debugStepLabel); #endif #if !defined(DISABLE_RECOMPILER_OPTIMIZATIONS) if (!mTryOptimize()) #endif mSingleInstruction(); if (m_checkAlertAfterInstruction) { mCheckAlert(); m_checkAlertAfterInstruction = false; } count--; } // in the end jump to next instruction label u16 endRecPc = m_recPc; m_recPc = instrPointer; mJump(endRecPc); // flush const pool or any other pending data in the assembler m_masm->flush(); // save translation end pointer for this page int recompiledEnd = m_masm->pcOffset(); m_pageTranslationOffset[page] = recompiledEnd; Q_ASSERT(page == 0 || recompiledEnd < (page+1) * BlockSize); // flush instruction cache int recompiledSize = recompiledEnd - recompiledStart; Cpu::flushICache(m_codeBuffer + recompiledStart, recompiledSize); // mark translation page used m_pageUsedMask |= 1 << page; // handle section boundary because 6502 has variable length of // instructions (m_recPc == 0 on KIL instruction so omit that value) int pageNow = nesCpuPageByAddr(m_recPc); if (m_recPc && pageNow != page) saveTranslationBoundary(page, m_recPc & NesCpuBankMask); } fixCallerInstruction(instrPointer, caller); return m_codeBuffer + m_labels[instrPointer].pos(); }
//! clears the zbuffer void CStencilBuffer::clear() { memset32 ( Buffer, 0, TotalSize ); }
int _main( int argc, char *argv[] ) { //BSS is in DATA section so IOS doesnt touch it, we need to manually clear it //dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start); memset32(&__bss_start, 0, &__bss_end - &__bss_start); sync_after_write(&__bss_start, &__bss_end - &__bss_start); s32 ret = 0; u32 HID_Thread = 0, DI_Thread = 0; u8 MessageHeap[0x10]; //u32 MessageQueue=0xFFFFFFFF; BootStatus(0, 0, 0); thread_set_priority( 0, 0x79 ); // do not remove this, this waits for FS to be ready! thread_set_priority( 0, 0x50 ); thread_set_priority( 0, 0x79 ); //MessageQueue = ES_Init( MessageHeap ); ES_Init( MessageHeap ); BootStatus(1, 0, 0); #ifndef NINTENDONT_USB BootStatus(2, 0, 0); ret = SDHCInit(); if(!ret) { dbgprintf("SD:SDHCInit() failed:%d\r\n", ret ); BootStatusError(-2, ret); mdelay(2000); Shutdown(); } #endif BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); s32 res = f_mount( 0, fatfs ); if( res != FR_OK ) { dbgprintf("ES:f_mount() failed:%d\r\n", res ); BootStatusError(-3, res); mdelay(2000); Shutdown(); } BootStatus(4, 0, 0); BootStatus(5, 0, 0); int MountFail = 0; s32 fres = -1; FIL fp; while(fres != FR_OK) { fres = f_open(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING); switch(fres) { case FR_OK: f_close(&fp); case FR_NO_PATH: case FR_NO_FILE: { fres = FR_OK; } break; default: case FR_DISK_ERR: { f_mount(0, NULL); //unmount drive todo: retry could never work MountFail++; if(MountFail == 10) { BootStatusError(-5, fres); mdelay(2000); Shutdown(); } mdelay(5); } break; } if(STATUS_ERROR == -7) { // FS check timed out on PPC side dbgprintf("FS check timed out\r\n"); mdelay(3000); Shutdown(); } } #ifndef NINTENDONT_USB s_size = 512; s_cnt = fatfs->n_fatent * fatfs->csize; #endif BootStatus(6, s_size, s_cnt); #ifdef NINTENDONT_USB s32 r = LoadModules(55); //dbgprintf("ES:ES_LoadModules(%d):%d\r\n", 55, r ); if( r < 0 ) { BootStatusError(-6, r); mdelay(2000); Shutdown(); } #endif BootStatus(7, s_size, s_cnt); ConfigInit(); if (ConfigGetConfig(NIN_CFG_LOG)) SDisInit = 1; // Looks okay after threading fix dbgprintf("Game path: %s\r\n", ConfigGetGamePath()); BootStatus(8, s_size, s_cnt); memset32((void*)0x13002800, 0, 0x30); sync_after_write((void*)0x13002800, 0x30); memset32((void*)0x13160000, 0, 0x20); sync_after_write((void*)0x13160000, 0x20); memset32((void*)0x13026500, 0, 0x100); sync_after_write((void*)0x13026500, 0x100); bool UseHID = ConfigGetConfig(NIN_CFG_HID); if( UseHID ) { ret = HIDInit(); if(ret < 0 ) { dbgprintf("ES:HIDInit() failed\r\n" ); BootStatusError(-8, ret); mdelay(2000); Shutdown(); } write32(0x13003004, 0); sync_after_write((void*)0x13003004, 0x20); HID_Thread = thread_create(HID_Run, NULL, HID_ThreadStack, 0x400, 0x78, 1); thread_continue(HID_Thread); } BootStatus(9, s_size, s_cnt); DIRegister(); DI_Thread = thread_create(DIReadThread, NULL, DI_ThreadStack, 0x400, 0x78, 1); thread_continue(DI_Thread); DIinit(true); BootStatus(10, s_size, s_cnt); GCAMInit(); EXIInit(); ret = Check_Cheats(); if(ret < 0 ) { dbgprintf("Check_Cheats failed\r\n" ); BootStatusError(-10, ret); mdelay(4000); Shutdown(); } BootStatus(11, s_size, s_cnt); bool PatchSI = !ConfigGetConfig(NIN_CFG_NATIVE_SI); if (PatchSI) SIInit(); StreamInit(); PatchInit(); //This bit seems to be different on japanese consoles u32 ori_ppcspeed = read32(HW_PPCSPEED); if((ConfigGetGameID() & 0xFF) == 'J') set32(HW_PPCSPEED, (1<<17)); else clear32(HW_PPCSPEED, (1<<17)); //write32( 0x1860, 0xdeadbeef ); // Clear OSReport area //Tell PPC side we are ready! cc_ahbMemFlush(1); mdelay(1000); BootStatus(0xdeadbeef, s_size, s_cnt); u32 Now = read32(HW_TIMER); u32 PADTimer = Now; u32 DiscChangeTimer = Now; u32 ResetTimer = Now; #ifdef NINTENDONT_USB u32 USBReadTimer = Now; #endif u32 Reset = 0; bool SaveCard = false; if( ConfigGetConfig(NIN_CFG_LED) ) { set32(HW_GPIO_ENABLE, GPIO_SLOT_LED); clear32(HW_GPIO_DIR, GPIO_SLOT_LED); clear32(HW_GPIO_OWNER, GPIO_SLOT_LED); } EnableAHBProt(-1); //disable AHBPROT write32(0xd8006a0, 0x30000004), mask32(0xd8006a8, 0, 2); //widescreen fix while (1) { _ahbMemFlush(0); //Check this. Purpose is to send another interrupt if wasn't processed /*if (((read32(0x14) != 0) || (read32(0x13026514) != 0)) && (read32(HW_ARMIRQFLAG) & (1 << 30)) == 0) { write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq }*/ #ifdef PATCHALL if (EXI_IRQ == true) { if(EXICheckTimer()) EXIInterrupt(); } #endif if ((PatchSI) && (SI_IRQ != 0)) { if (((read32(HW_TIMER) - PADTimer) > 7910) || (SI_IRQ & 0x2)) // about 240 times a second { SIInterrupt(); PADTimer = read32(HW_TIMER); } } if(DI_IRQ == true) { if(DI_CallbackMsg.result == 0) DIInterrupt(); } else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */ { if((read32(HW_TIMER) - Now) / 1898437 > 2) /* after 3 second earliest */ { EXISaveCard(); SaveCard = false; } } #ifdef NINTENDONT_USB else if((read32(HW_TIMER) - USBReadTimer) / 1898437 > 9) /* Read random sector after about 10 seconds */ { DI_CallbackMsg.result = -1; sync_after_write(&DI_CallbackMsg, 0x20); IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg ); while(DI_CallbackMsg.result) { udelay(10); //wait for other threads BTUpdateRegisters(); } USBReadTimer = read32(HW_TIMER); } #endif udelay(10); //wait for other threads //Baten Kaitos save hax /*if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } }*/ if ( DiscChangeIRQ == 1 ) { DiscChangeTimer = read32(HW_TIMER); DiscChangeIRQ = 2; } else if ( DiscChangeIRQ == 2 ) { if ( (read32(HW_TIMER) - DiscChangeTimer ) > 2 * 243000000 / 128) { //dbgprintf("DIP:IRQ mon!\r\n"); set32( DI_SSTATUS, 0x3A ); sync_after_write((void*)DI_SSTATUS, 4); DIInterrupt(); DiscChangeIRQ = 0; } } _ahbMemFlush(1); DIUpdateRegisters(); #ifdef PATCHALL EXIUpdateRegistersNEW(); GCAMUpdateRegisters(); BTUpdateRegisters(); #endif StreamUpdateRegisters(); CheckOSReport(); if(EXICheckCard()) { Now = read32(HW_TIMER); SaveCard = true; } if (PatchSI) { SIUpdateRegisters(); if (read32(DIP_IMM) == 0x1DEA) { DIFinishAsync(); break; } if (read32(DIP_IMM) == 0x3DEA) { if (Reset == 0) { dbgprintf("Fake Reset IRQ\n"); write32(EXI2DATA, 0x2); // Reset irq write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq Reset = 1; } } else if (Reset == 1) { write32(EXI2DATA, 0x10000); // send pressed ResetTimer = read32(HW_TIMER); Reset = 2; } /* The cleanup is not connected to the button press */ if (Reset == 2) { if ((read32(HW_TIMER) - ResetTimer) / 949219 > 0) //free after half a second { write32(EXI2DATA, 0); // done, clear write32(DIP_IMM, 0); Reset = 0; } } } if(read32(DIP_IMM) == 0x4DEA) PatchGame(); CheckPatchPrs(); if(read32(HW_GPIO_IN) & GPIO_POWER) { DIFinishAsync(); #ifdef PATCHALL BTE_Shutdown(); #endif Shutdown(); } //sync_before_read( (void*)0x1860, 0x20 ); //if( read32(0x1860) != 0xdeadbeef ) //{ // if( read32(0x1860) != 0 ) // { // dbgprintf( (char*)(P2C(read32(0x1860))), // (char*)(P2C(read32(0x1864))), // (char*)(P2C(read32(0x1868))), // (char*)(P2C(read32(0x186C))), // (char*)(P2C(read32(0x1870))), // (char*)(P2C(read32(0x1874))) // ); // } // write32(0x1860, 0xdeadbeef); // sync_after_write( (void*)0x1860, 0x20 ); //} cc_ahbMemFlush(1); } if( UseHID ) { /* we're done reading inputs */ thread_cancel(HID_Thread, 0); } IOS_Close(DI_Handle); //close game thread_cancel(DI_Thread, 0); DIUnregister(); write32( DIP_IMM, 0 ); /* reset time */ while(1) { if(read32(DIP_IMM) == 0x2DEA) break; wait_for_ppc(1); } if( ConfigGetConfig(NIN_CFG_LED) ) clear32(HW_GPIO_OUT, GPIO_SLOT_LED); if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) ) EXIShutdown(); if (ConfigGetConfig(NIN_CFG_LOG)) closeLog(); #ifdef PATCHALL BTE_Shutdown(); #endif //unmount FAT device f_mount(0, NULL); #ifndef NINTENDONT_USB SDHCShutdown(); #endif //make sure we set that back to the original write32(HW_PPCSPEED, ori_ppcspeed); IOSBoot((char*)0x13003020, 0, read32(0x13003000)); return 0; }
void FFS_Ioctlv(struct IPCMessage *msg) { u32 InCount = msg->ioctlv.argc_in; u32 OutCount = msg->ioctlv.argc_io; vector *v = (vector*)(msg->ioctlv.argv); s32 ret=0; #ifdef EDEBUG dbgprintf("FFS:IOS_Ioctlv( %d, 0x%x 0x%x 0x%x 0x%p )\n", msg->fd, msg->ioctl.command, InCount, OutCount, msg->ioctlv.argv ); #endif //for( ret=0; ret<InCount+OutCount; ++ret) //{ // if( ((vu32)(v[ret].data)>>24) == 0 ) // dbgprintf("FFS:in:0x%08x\tout:0x%08x\n", v[ret].data, v[ret].data ); //} switch(msg->ioctl.command) { case 0x60: { HAXHandle = FS_Open( (char*)(v[0].data), (u32)(v[1].data) ); #ifdef DEBUG dbgprintf("FS_Open(%s, %02X):%d\n", (char*)(v[0].data), (u32)(v[1].data), HAXHandle ); #endif ret = HAXHandle; } break; case IOCTL_READDIR: { if( InCount == 1 && OutCount == 1 ) { ret = FS_ReadDir( (char*)(v[0].data), (u32*)(v[1].data), NULL ); } else if( InCount == 2 && OutCount == 2 ) { char *buf = heap_alloc_aligned( 0, v[2].len, 0x40 ); memset32( buf, 0, v[2].len ); ret = FS_ReadDir( (char*)(v[0].data), (u32*)(v[3].data), buf ); memcpy( (char*)(v[2].data), buf, v[2].len ); heap_free( 0, buf ); } else { ret = FS_EFATAL; } #ifdef DEBUG dbgprintf("FFS:ReadDir(\"%s\"):%d FileCount:%d\n", (char*)(v[0].data), ret, *(u32*)(v[1].data) ); #endif } break; case IOCTL_GETUSAGE: { if( memcmp( (char*)(v[0].data), "/title/00010001", 16 ) == 0 ) { *(u32*)(v[1].data) = 23; // size is size/0x4000 *(u32*)(v[2].data) = 42; // empty folders return a FileCount of 1 } else if( memcmp( (char*)(v[0].data), "/title/00010005", 16 ) == 0 ) // DLC { *(u32*)(v[1].data) = 23; // size is size/0x4000 *(u32*)(v[2].data) = 42; // empty folders return a FileCount of 1 } else { *(u32*)(v[1].data) = 0; // size is size/0x4000 *(u32*)(v[2].data) = 1; // empty folders return a FileCount of 1 ret = FS_GetUsage( (char*)(v[0].data), (u32*)(v[2].data), (u32*)(v[1].data) ); //Size is returned in BlockCount *(u32*)(v[1].data) = *(u32*)(v[1].data) / 0x4000; } #ifdef DEBUG dbgprintf("FFS:FS_GetUsage(\"%s\"):%d FileCount:%d FileSize:%d\n", (char*)(v[0].data), ret, *(u32*)(v[2].data), *(u32*)(v[1].data) ); #endif } break; default: { //dbgprintf("FFS:IOS_Ioctlv( %d, 0x%x 0x%x 0x%x 0x%p )\n", msg->fd, msg->ioctl.command, InCount, OutCount, msg->ioctlv.argv ); ret = -1017; } break; } #ifdef DEBUG //dbgprintf("FFS:IOS_Ioctlv():%d\n", ret); #endif mqueue_ack( (void *)msg, ret); }
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ int load_565rle_image(char *filename, bool bf_supported) { struct fb_info *info; int fd, count, err = 0; unsigned max; unsigned short *data, *ptr ; uint32_t *bits; unsigned int out; info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; goto err_logo_free_data; } max = fb_width(info) * fb_height(info); ptr = data; if (bf_supported && (info->node == 1 || info->node == 2)) { err = -EPERM; pr_err("%s:%d no info->creen_base on fb%d!\n", __func__, __LINE__, info->node); goto err_logo_free_data; } bits = (uint32_t*)(info->screen_base); while (count > 3) { unsigned n = ptr[0]; if (n > max) break; out = rgb32(ptr[1]); memset32(bits, out, n << 2); bits += n; max -= n; ptr += 2; count -= 4; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
//u32 Loopmode=0; int _main( int argc, char *argv[] ) { s32 ret = 0; u8 MessageHeap[0x10]; //u32 MessageQueue=0xFFFFFFFF; BootStatus(0, 0, 0); thread_set_priority( 0, 0x79 ); // do not remove this, this waits for FS to be ready! thread_set_priority( 0, 0x50 ); thread_set_priority( 0, 0x79 ); //MessageQueue = ES_Init( MessageHeap ); ES_Init( MessageHeap ); BootStatus(1, 0, 0); #ifndef NINTENDONT_USB BootStatus(2, 0, 0); ret = SDHCInit(); if(!ret) { dbgprintf("SD:SDHCInit() failed:%d\r\n", ret ); BootStatusError(-2, ret); mdelay(2000); Shutdown(); } #endif BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); s32 res = f_mount( 0, fatfs ); if( res != FR_OK ) { dbgprintf("ES:f_mount() failed:%d\r\n", res ); BootStatusError(-3, res); mdelay(2000); Shutdown(); } BootStatus(4, 0, 0); BootStatus(5, 0, 0); int MountFail = 0; s32 fres = -1; while(fres != FR_OK) { fres = f_open(&GameFile, "/bladie", FA_READ|FA_OPEN_EXISTING); switch(fres) { case FR_OK: f_close(&GameFile); case FR_NO_PATH: case FR_NO_FILE: { fres = FR_OK; } break; default: case FR_DISK_ERR: { f_mount(0, 0); //unmount drive todo: retry could never work MountFail++; if(MountFail == 10) { BootStatusError(-5, fres); mdelay(2000); Shutdown(); } mdelay(5); } break; } } #ifdef NINTENDONT_USB BootStatus(6, s_size, s_cnt); s32 r = LoadModules(55); //dbgprintf("ES:ES_LoadModules(%d):%d\r\n", 55, r ); if( r < 0 ) { BootStatusError(-6, r); mdelay(2000); Shutdown(); } #endif BootStatus(7, s_size, s_cnt); ConfigInit(); BootStatus(8, s_size, s_cnt); SDisInit = 1; memset32((void*)0x13002800, 0, 0x30); sync_after_write((void*)0x13002800, 0x30); u32 HID_Thread = 0; bool UseHID = ConfigGetConfig(NIN_CFG_HID); if( UseHID ) { ret = HIDInit(); if(ret < 0 ) { dbgprintf("ES:HIDInit() failed\r\n" ); BootStatusError(-8, ret); mdelay(2000); Shutdown(); } write32(0x13003004, 0); sync_after_write((void*)0x13003004, 0x20); memset32((void*)0x13003420, 0, 0x1BE0); sync_after_write((void*)0x13003420, 0x1BE0); HID_Thread = thread_create(HID_Run, NULL, (u32*)0x13003420, 0x1BE0, 0x78, 1); thread_continue(HID_Thread); } BootStatus(9, s_size, s_cnt); DIinit(); BootStatus(10, s_size, s_cnt); EXIInit(); BootStatus(11, s_size, s_cnt); SIInit(); //fixes issues in some japanese games if((ConfigGetGameID() & 0xFF) == 'J') write32(HW_PPCSPEED, 0x2A9E0); //Tell PPC side we are ready! cc_ahbMemFlush(1); mdelay(1000); BootStatus(0xdeadbeef, s_size, s_cnt); /* write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( HW_PPCIRQMASK, (1<<31) ); set32( HW_IPC_PPCCTRL, 0x30 ); */ u32 Now = read32(HW_TIMER); u32 PADTimer = Now; bool SaveCard = false; if( ConfigGetConfig(NIN_CFG_LED) ) { set32(HW_GPIO_ENABLE, GPIO_SLOT_LED); clear32(HW_GPIO_DIR, GPIO_SLOT_LED); clear32(HW_GPIO_OWNER, GPIO_SLOT_LED); } write32(0xd8006a0, 0x30000004), mask32(0xd8006a8, 0, 2); while (1) { _ahbMemFlush(0); if(EXI_IRQ == true) { if(EXICheckTimer()) EXIInterrupt(); } if(SI_IRQ == true) { if((read32(HW_TIMER) - PADTimer) >= 65000) // about 29 times a second { SIInterrupt(); PADTimer = read32(HW_TIMER); } } if(DI_IRQ == true) { if(DI_Args->Buffer == 0xdeadbeef) DIInterrupt(); } else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */ { if((read32(HW_TIMER) - Now) / 1898437 > 2) /* after 3 second earliest */ { EXISaveCard(); SaveCard = false; } } udelay(10); //wait for other threads //Baten Kaitos save hax if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } } if( Streaming ) { if( (read32(HW_TIMER) * 19 / 10) - StreamTimer >= 5000000 ) { // dbgprintf("."); StreamOffset += 64*1024; if( StreamOffset >= StreamSize ) { StreamOffset = StreamSize; Streaming = 0; } StreamTimer = read32(HW_TIMER) * 19 / 10; } } if( DiscChangeIRQ ) { if( read32(HW_TIMER) * 128 / 243000000 > 2 ) { //dbgprintf("DIP:IRQ mon!\r\n"); set32( DI_SSTATUS, 0x3A ); sync_after_write((void*)DI_SSTATUS, 4); DIInterrupt(); DiscChangeIRQ = 0; } } _ahbMemFlush(1); DIUpdateRegisters(); EXIUpdateRegistersNEW(); SIUpdateRegisters(); if(EXICheckCard()) { Now = read32(HW_TIMER); SaveCard = true; } if(read32(DI_SCONFIG) == 0x1DEA) { while(DI_Args->Buffer != 0xdeadbeef) udelay(100); break; } cc_ahbMemFlush(1); } if( UseHID ) { /* we're done reading inputs */ thread_cancel(HID_Thread, 0); } thread_cancel(DI_Thread, 0); write32( DI_SCONFIG, 0 ); sync_after_write( (void*)DI_SCONFIG, 4 ); /* reset time */ while(1) { _ahbMemFlush(0); sync_before_read( (void*)DI_SCONFIG, 4 ); if(read32(DI_SCONFIG) == 0x2DEA) break; wait_for_ppc(1); cc_ahbMemFlush(1); } if( ConfigGetConfig(NIN_CFG_LED) ) clear32(HW_GPIO_OUT, GPIO_SLOT_LED); if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) ) EXIShutdown(); IOSBoot((char*)0x13003020, 0, read32(0x13003000)); return 0; }
void emu_video_mode_change(int start_line, int line_count, int is_32cols) { // clear whole screen in all buffers memset32(g_screen_ptr, 0, g_screen_ppitch * g_screen_height * 2 / 4); }
void plat_status_msg_clear(void) { unsigned short *d = (unsigned short *)g_screen_ptr + g_screen_ppitch * g_screen_height; int l = g_screen_ppitch * 8; memset32((int *)(d - l), 0, l * 2 / 4); }
int up_create_stack(_TCB *tcb, size_t stack_size) { if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) { sched_free(tcb->stack_alloc_ptr); tcb->stack_alloc_ptr = NULL; } if (!tcb->stack_alloc_ptr) { #ifdef CONFIG_DEBUG tcb->stack_alloc_ptr = (uint32_t*)kzalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t*)kmalloc(stack_size); #endif } if (tcb->stack_alloc_ptr) { size_t top_of_stack; size_t size_of_stack; /* The ARM uses a push-down stack: the stack grows toward lower * addresses in memory. The stack pointer register, points to * the lowest, valid work address (the "top" of the stack). Items * on the stack are referenced as positive word offsets from sp. */ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; /* The ARM stack must be aligned; 4 byte alignment for OABI and * 8-byte alignment for EABI. If necessary top_of_stack must be * rounded down to the next boundary */ top_of_stack = STACK_ALIGN_DOWN(top_of_stack); /* The size of the stack in bytes is then the difference between * the top and the bottom of the stack (+4 because if the top * is the same as the bottom, then the size is one 32-bit element). * The size need not be aligned. */ size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the _TCB */ tcb->adj_stack_ptr = (uint32_t*)top_of_stack; tcb->adj_stack_size = size_of_stack; /* If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK) memset32(tcb->stack_alloc_ptr, 0xDEADBEEF, tcb->adj_stack_size/4); #endif up_ledon(LED_STACKCREATED); return OK; } return ERROR; }
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ int load_565rle_image(char *filename) { struct fb_info *info; int fd, err = 0; unsigned count, max, width, stride, line_pos = 0; unsigned short *data, *ptr; unsigned char *bits; info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } if (!info->screen_base) { printk(KERN_WARNING "Framebuffer memory not allocated\n"); return -ENOMEM; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; goto err_logo_free_data; } width = fb_width(info); stride = fb_linewidth(info); max = width * fb_height(info); ptr = data; bits = (unsigned char *)(info->screen_base); while (count > 3) { int n = ptr[0]; if (n > max) break; max -= n; while (n > 0) { unsigned int j = (line_pos + n > width ? width-line_pos : n); if (fb_depth(info) == 2) memset16(bits, ptr[1], j << 1); else { unsigned int widepixel = ptr[1]; /* * Format is RGBA, but fb is big * endian so we should make widepixel * as ABGR. */ widepixel = /* red : f800 -> 000000f8 */ (widepixel & 0xf800) >> 8 | /* green : 07e0 -> 0000fc00 */ (widepixel & 0x07e0) << 5 | /* blue : 001f -> 00f80000 */ (widepixel & 0x001f) << 19; memset32(bits, widepixel, j << 2); } bits += j * fb_depth(info); line_pos += j; n -= j; if (line_pos == width) { bits += (stride-width) * fb_depth(info); line_pos = 0; } } ptr += 2; count -= 4; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
s32 FS_GetUsage( char *path, u32 *FileCount, u32 *TotalSize ) { char *file = heap_alloc_aligned( 0, 0x40, 0x40 ); DIR d; FILINFO FInfo; s32 res=0; switch( f_opendir( &d, path ) ) { case FR_INVALID_NAME: case FR_NO_FILE: case FR_NO_PATH: return FS_ENOENT2; default: return FS_EFATAL; case FR_OK: break; } while( (res = f_readdir( &d, &FInfo )) == FR_OK ) { #ifdef USEATTR if( FInfo.lfsize ) { if( strstr( FInfo.lfname, ".attr" ) != NULL ) continue; } else{ if( strstr( FInfo.fname, ".attr" ) != NULL ) continue; } #endif if( FInfo.fattrib & AM_DIR ) { memset32( file, 0, 0x40 ); memcpy( file, path, strlen(path) ); //insert slash file[strlen(path)] = '/'; if( FInfo.lfsize ) { memcpy( file+strlen(path)+1, FInfo.lfname, strlen(FInfo.lfname) ); } else { memcpy( file+strlen(path)+1, FInfo.fname, strlen(FInfo.fname) ); } res = FS_GetUsage( file, FileCount, TotalSize ); if( res != FS_SUCCESS ) { heap_free( 0, file ); return res; } } else { *FileCount = *FileCount + 1; *TotalSize = *TotalSize + FInfo.fsize; } } heap_free( 0, file ); return FS_SUCCESS; }
void* CS_malloc(size_t size) { size = ((size + 3) & 0xFFFFFFFC); void* ptr = malloc(size); if(ptr) { memset32(ptr, 0, size); } return ptr; }
s32 FS_Open( char *Path, u8 Mode ) { if( strncmp( Path, "/AX", 3 ) == 0 ) return HAXHandle; // Is it a device? if( strncmp( Path, "/dev/", 5 ) == 0 ) { if( strncmp( Path+5, "fs", 2 ) == 0) { return FS_FD; }/* else if( strncmp( Path+5, "flash", 5) == 0) { return FL_FD; } else if( strncmp(CMessage->open.device+5, "boot2", 5) == 0) { return B2_FD; }*/ else { // Not a devicepath of ours, dispatch it to the syscall again.. return FS_NO_DEVICE; } } else { // Or is it a filepath ? //if( (strstr( Path, "data/setting.txt") != NULL) && (Mode&2) ) //{ // return FS_NO_ACCESS; //} u32 i = 0; while( i < MAX_FILE ) { if( fd_stack[i].fs == NULL ) break; i++; } if( i == MAX_FILE ) return FS_NO_HANDLE; switch( f_open( &fd_stack[i], Path, Mode ) ) { case FR_OK: { ; } break; case FR_NO_FILE: { if( ( *(vu32*)0 >> 8 ) == 0x525559 ) // HACK: for whatever reason NMH2 fails when -106(FS_NO_ENTRY) is returned { // Most games don't seem to mind the change but it breaks MH Tri so we need a hack. if( f_open( &fd_stack[i], Path, Mode | FA_OPEN_ALWAYS ) == FR_OK ) { return i; } } memset32( &fd_stack[i], 0, sizeof(FIL) ); return FS_NO_ENTRY; } break; default: { memset32( &fd_stack[i], 0, sizeof(FIL) ); return FS_NO_ENTRY; } break; } return i; } return FS_FATAL; }
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* Is there already a stack allocated of a different size? Because of * alignment issues, stack_size might erroneously appear to be of a * different size. Fortunately, this is not a critical operation. */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) { /* Yes.. Release the old stack */ up_release_stack(tcb, ttype); } /* Do we need to allocate a new stack? */ if (!tcb->stack_alloc_ptr) { /* Allocate the stack. If DEBUG is enabled (but not stack debug), * then create a zeroed stack to make stack dumps easier to trace. */ #if defined(CONFIG_NUTTX_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Use the kernel allocator if this is a kernel thread */ if (ttype == TCB_FLAG_TTYPE_KERNEL) { #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK) tcb->stack_alloc_ptr = (uint32_t *)kzalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t *)kmalloc(stack_size); #endif } else #endif { /* Use the user-space allocator if this is a task or pthread */ #if defined(CONFIG_DEBUG) && !defined(CONFIG_DEBUG_STACK) tcb->stack_alloc_ptr = (uint32_t *)kuzalloc(stack_size); #else tcb->stack_alloc_ptr = (uint32_t *)kumalloc(stack_size); #endif } #ifdef CONFIG_DEBUG /* Was the allocation successful? */ if (!tcb->stack_alloc_ptr) { sdbg("ERROR: Failed to allocate stack, size %d\n", stack_size); } #endif } /* Did we successfully allocate a stack? */ if (tcb->stack_alloc_ptr) { size_t top_of_stack; size_t size_of_stack; /* The ARM uses a push-down stack: the stack grows toward lower * addresses in memory. The stack pointer register, points to * the lowest, valid work address (the "top" of the stack). Items * on the stack are referenced as positive word offsets from sp. */ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; /* The ARM stack must be aligned; 4 byte alignment for OABI and * 8-byte alignment for EABI. If necessary top_of_stack must be * rounded down to the next boundary */ top_of_stack = STACK_ALIGN_DOWN(top_of_stack); /* The size of the stack in bytes is then the difference between * the top and the bottom of the stack (+4 because if the top * is the same as the bottom, then the size is one 32-bit element). * The size need not be aligned. */ size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ tcb->adj_stack_ptr = (uint32_t*)top_of_stack; tcb->adj_stack_size = size_of_stack; /* If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ #if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_STACK) memset32(tcb->stack_alloc_ptr, 0xdeadbeef, tcb->adj_stack_size/4); #endif up_ledon(LED_STACKCREATED); return OK; } return ERROR; }
static void bpf_jit_fill_ill_insns(void *area, unsigned int size) { memset32(area, BREAKPOINT_INSTRUCTION, size/4); }
void memset32_uncached(int *dest, int c, int count) { memset32(dest, c, count); }
int sky_lcdc_display_loadingbar(int ratio) { struct fb_info *info; int err = 0; #ifdef CONFIG_PANTECH_FB_24BPP_RGB888 IBUF_TYPE *load_bar; unsigned int i; IBUF_TYPE BAR_COLOR = 0xFFFF; #else unsigned short *load_bar; unsigned short i; unsigned short BAR_COLOR = 0xFFFF; #endif #if defined(CONFIG_MACH_MSM8X55_MINI) const unsigned short ST_X=100, ST_Y=738; const unsigned short SCREEN_WIDTH = 608; const unsigned short BAR_WIDTH =418; #elif defined(CONFIG_MACH_MSM8X55_LASER2) const unsigned short ST_X=40, ST_Y=738; const unsigned short SCREEN_WIDTH = 480; const unsigned short BAR_WIDTH = 400; #else const unsigned short ST_X=100, ST_Y=738; const unsigned short SCREEN_WIDTH = 480; const unsigned short BAR_WIDTH = 441; #endif const unsigned short BAR_HEIGHT = 17; int cr = 0; if (ratio > 100) ratio = 100; cr = (int)(ratio * BAR_WIDTH/100 ); info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n",__FUNCTION__); return -ENODEV; } #ifdef CONFIG_PANTECH_FB_24BPP_RGB888 //#ifdef CONFIG_MACH_MSM8X55_MINI // load_bar = (IBUF_TYPE *)(info->screen_base) + (SCREEN_WIDTH * ST_Y + ST_X); //#endif load_bar = (IBUF_TYPE *)(info->screen_base) + SCREEN_WIDTH * ST_Y + ST_X; #else load_bar = (unsigned short *)(info->screen_base) + SCREEN_WIDTH * ST_Y + ST_X; #endif for (i=0 ; i<BAR_HEIGHT; i++) { BAR_COLOR = loading_progress_t[i]; #ifdef CONFIG_PANTECH_FB_24BPP_RGB888 memset32((unsigned int *)load_bar, BAR_COLOR, cr<<2); #else memset16(load_bar, BAR_COLOR, cr<<1); #endif load_bar = load_bar + SCREEN_WIDTH; } return err; }
static inline void installer(u32 a9lhBoot) { if(!mountSD()) shutdown(1, "Error: failed to mount the SD card"); const char *path; u32 updatea9lh = 0; //If making a first install, we need the OTP if(!a9lhBoot) { //Read OTP path = "homebrew/3ds/ShadowNAND_Installer/otp.bin"; if(fileRead((void *)OTP_OFFSET, path) != 256) { const u8 zeroes[256] = {0}; if(memcmp((void *)OTP_FROM_MEM, zeroes, 256) == 0) shutdown(1, "Error: otp.bin doesn't exist and can't be dumped"); fileWrite((void *)OTP_FROM_MEM, path, 256); memcpy((void *)OTP_OFFSET, (void *)OTP_FROM_MEM, 256); } } //Setup the key sector de/encryption with the SHA register or otp.bin setupKeyslot0x11(a9lhBoot, (void *)OTP_OFFSET); //Calculate the CTR for the 3DS partitions getNandCTR(); //Get NAND FIRM0 and test that the CTR is correct readFirm0((u8 *)FIRM0_OFFSET, FIRM0_SIZE); if(memcmp((void *)FIRM0_OFFSET, "FIRM", 4) != 0) shutdown(1, "Error: failed to setup FIRM encryption"); //If booting from A9LH or on N3DS, we can use the key sector from NAND if(a9lhBoot || console) { updatea9lh = 1; //Read decrypted key sector path = "homebrew/3ds/ShadowNAND_Installer/secret_sector.bin"; if(fileRead((void *)SECTOR_OFFSET, path) != 0x200) shutdown(1, "Error: secret_sector.bin doesn't exist or has\na wrong size"); if(!verifyHash((void *)SECTOR_OFFSET, 0x200, sectorHash)) shutdown(1, "Error: secret_sector.bin is invalid or corrupted"); } if(!a9lhBoot || updatea9lh) { //Generate and encrypt a per-console A9LH key sector generateSector((u8 *)SECTOR_OFFSET, 0); //Read FIRM0 path = "homebrew/3ds/ShadowNAND_Installer/firm0.bin"; if(fileRead((void *)FIRM0_OFFSET, path) != FIRM0_SIZE) shutdown(1, "Error: firm0.bin doesn't exist or has a wrong size"); if(!verifyHash((void *)FIRM0_OFFSET, FIRM0_SIZE, firm0Hash)) shutdown(1, "Error: firm0.bin is invalid or corrupted"); } if(!a9lhBoot) { //Read FIRM1 path = "homebrew/3ds/ShadowNAND_Installer/firm1.bin"; if(fileRead((void *)FIRM1_OFFSET, path) != FIRM1_SIZE) shutdown(1, "Error: firm1.bin doesn't exist or has a wrong size"); if(!verifyHash((void *)FIRM1_OFFSET, FIRM1_SIZE, firm1Hash)) shutdown(1, "Error: firm1.bin is invalid or corrupted"); } //Inject stage1 memset32((void *)STAGE1_OFFSET, 0, MAX_STAGE1_SIZE); path = "homebrew/3ds/ShadowNAND_Installer/payload_stage1.bin"; u32 size = fileRead((void *)STAGE1_OFFSET, path); if(!size || size > MAX_STAGE1_SIZE) shutdown(1, "Error: payload_stage1.bin doesn't exist or\nexceeds max size"); const u8 zeroes[688] = {0}; if(memcmp(zeroes, (void *)STAGE1_OFFSET, 688) == 0) shutdown(1, "Error: the payload_stage1.bin you're attempting\nto install is not compatible"); //Read stage2 memset32((void *)STAGE2_OFFSET, 0, MAX_STAGE2_SIZE); path = "homebrew/3ds/ShadowNAND_Installer/payload_stage2.bin"; size = fileRead((void *)STAGE2_OFFSET, path); if(!size || size > MAX_STAGE2_SIZE) shutdown(1, "Error: payload_stage2.bin doesn't exist or\nexceeds max size"); //Read alt_stage2 memset32((void *)ALTSTAGE2_OFFSET, 0, MAX_ALTSTAGE2_SIZE); path = "homebrew/3ds/ShadowNAND_Installer/payload_altstage2.bin"; size = fileRead((void *)ALTSTAGE2_OFFSET, path); if(!size || size > MAX_ALTSTAGE2_SIZE) shutdown(1, "Error: payload_altstage2.bin doesn't exist or\nexceeds max size"); posY = drawString("All checks passed, installing...", 10, posY + SPACING_Y, COLOR_WHITE); //Point of no return, install stuff in the safest order sdmmc_nand_writesectors(0x5A000, 0x20, (vu8 *)ALTSTAGE2_OFFSET); sdmmc_nand_writesectors(0x5C000, 0x20, (vu8 *)STAGE2_OFFSET); if(!a9lhBoot) writeFirm((u8 *)FIRM1_OFFSET, 1, FIRM1_SIZE); if(!a9lhBoot || updatea9lh) sdmmc_nand_writesectors(0x96, 1, (vu8 *)SECTOR_OFFSET); writeFirm((u8 *)FIRM0_OFFSET, 0, FIRM0_SIZE); shutdown(2, a9lhBoot ? "Update: success!" : "Full install: success!"); }
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ int load_565rle_image(char *filename) { struct fb_info *info; int fd, count, err = 0; unsigned max; #ifdef CONFIG_PANTECH_FB_24BPP_RGB888 IBUF_TYPE *data, *bits, *ptr; #else unsigned short *data, *bits, *ptr; #endif info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; goto err_logo_free_data; } max = fb_width(info) * fb_height(info); ptr = data; #ifdef CONFIG_PANTECH_FB_24BPP_RGB888 bits = (IBUF_TYPE *)(info->screen_base); #else bits = (unsigned short *)(info->screen_base); #endif while (count > 3) { unsigned n = ptr[0]; if (n > max) break; #ifdef CONFIG_PANTECH_FB_24BPP_RGB888 memset32((unsigned int *)bits, ptr[1], n << 2); #else memset16(bits, ptr[1], n << 1); #endif bits += n; max -= n; ptr += 2; count -= 4; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
int _main( int argc, char *argv[] ) { //BSS is in DATA section so IOS doesnt touch it, we need to manually clear it //dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start); memset32(&__bss_start, 0, &__bss_end - &__bss_start); sync_after_write(&__bss_start, &__bss_end - &__bss_start); s32 ret = 0; u32 DI_Thread = 0; u8 MessageHeap[0x10]; BootStatus(0, 0, 0); thread_set_priority( 0, 0x79 ); // do not remove this, this waits for FS to be ready! thread_set_priority( 0, 0x50 ); thread_set_priority( 0, 0x79 ); //Disable AHBPROT EnableAHBProt(-1); //Load IOS Modules ES_Init( MessageHeap ); //Early HID for loader HIDInit(); //Enable DVD Access write32(HW_DIFLAGS, read32(HW_DIFLAGS) & ~DI_DISABLEDVD); dbgprintf("Sending signal to loader\r\n"); BootStatus(1, 0, 0); mdelay(10); //Loader running, selects games while(1) { sync_before_read((void*)RESET_STATUS, 0x20); vu32 reset_status = read32(RESET_STATUS); if(reset_status != 0) { if(reset_status == 0x0DEA) break; //game selected else if(reset_status == 0x1DEA) goto DoIOSBoot; //exit write32(RESET_STATUS, 0); sync_after_write((void*)RESET_STATUS, 0x20); } HIDUpdateRegisters(1); mdelay(10); } ConfigSyncBeforeRead(); u32 UseUSB = ConfigGetConfig(NIN_CFG_USB); SetDiskFunctions(UseUSB); BootStatus(2, 0, 0); if(UseUSB) { ret = USBStorage_Startup(); dbgprintf("USB:Drive size: %dMB SectorSize:%d\r\n", s_cnt / 1024 * s_size / 1024, s_size); } else { s_size = PAGE_SIZE512; //manually set s_size ret = SDHCInit(); } if(ret != 1) { dbgprintf("Device Init failed:%d\r\n", ret ); BootStatusError(-2, ret); mdelay(4000); Shutdown(); } //Verification if we can read from disc if(memcmp(ConfigGetGamePath(), "di", 3) == 0) RealDI_Init(); //will shutdown on fail BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); s32 res = f_mount( fatfs, fatDevName, 1 ); if( res != FR_OK ) { dbgprintf("ES:f_mount() failed:%d\r\n", res ); BootStatusError(-3, res); mdelay(4000); Shutdown(); } BootStatus(4, 0, 0); BootStatus(5, 0, 0); FIL fp; s32 fres = f_open_char(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING); switch(fres) { case FR_OK: f_close(&fp); case FR_NO_PATH: case FR_NO_FILE: { fres = FR_OK; } break; default: case FR_DISK_ERR: { BootStatusError(-5, fres); mdelay(4000); Shutdown(); } break; } if(!UseUSB) //Use FAT values for SD s_cnt = fatfs->n_fatent * fatfs->csize; BootStatus(6, s_size, s_cnt); BootStatus(7, s_size, s_cnt); ConfigInit(); if (ConfigGetConfig(NIN_CFG_LOG)) SDisInit = 1; // Looks okay after threading fix dbgprintf("Game path: %s\r\n", ConfigGetGamePath()); BootStatus(8, s_size, s_cnt); memset32((void*)RESET_STATUS, 0, 0x20); sync_after_write((void*)RESET_STATUS, 0x20); memset32((void*)0x13002800, 0, 0x30); sync_after_write((void*)0x13002800, 0x30); memset32((void*)0x13160000, 0, 0x20); sync_after_write((void*)0x13160000, 0x20); memset32((void*)0x13026500, 0, 0x100); sync_after_write((void*)0x13026500, 0x100); BootStatus(9, s_size, s_cnt); DIRegister(); DI_Thread = thread_create(DIReadThread, NULL, ((u32*)&__di_stack_addr), ((u32)(&__di_stack_size)) / sizeof(u32), 0x78, 1); thread_continue(DI_Thread); DIinit(true); BootStatus(10, s_size, s_cnt); GCAMInit(); EXIInit(); BootStatus(11, s_size, s_cnt); SIInit(); StreamInit(); PatchInit(); //Tell PPC side we are ready! cc_ahbMemFlush(1); mdelay(1000); BootStatus(0xdeadbeef, s_size, s_cnt); mdelay(1000); //wait before hw flag changes dbgprintf("Kernel Start\r\n"); //write32( 0x1860, 0xdeadbeef ); // Clear OSReport area //sync_after_write((void*)0x1860, 0x20); u32 Now = read32(HW_TIMER); u32 PADTimer = Now; u32 DiscChangeTimer = Now; u32 ResetTimer = Now; u32 InterruptTimer = Now; USBReadTimer = Now; u32 Reset = 0; bool SaveCard = false; if( ConfigGetConfig(NIN_CFG_LED) ) { set32(HW_GPIO_ENABLE, GPIO_SLOT_LED); clear32(HW_GPIO_DIR, GPIO_SLOT_LED); clear32(HW_GPIO_OWNER, GPIO_SLOT_LED); } set32(HW_GPIO_ENABLE, GPIO_SENSOR_BAR); clear32(HW_GPIO_DIR, GPIO_SENSOR_BAR); clear32(HW_GPIO_OWNER, GPIO_SENSOR_BAR); set32(HW_GPIO_OUT, GPIO_SENSOR_BAR); //turn on sensor bar write32( HW_PPCIRQMASK, (1<<30) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); //This bit seems to be different on japanese consoles u32 ori_ppcspeed = read32(HW_PPCSPEED); if((ConfigGetGameID() & 0xFF) == 'J') set32(HW_PPCSPEED, (1<<17)); else clear32(HW_PPCSPEED, (1<<17)); u32 ori_widesetting = read32(0xd8006a0); if(IsWiiU) { if( ConfigGetConfig(NIN_CFG_WIIU_WIDE) ) write32(0xd8006a0, 0x30000004); else write32(0xd8006a0, 0x30000002); mask32(0xd8006a8, 0, 2); } while (1) { _ahbMemFlush(0); //Does interrupts again if needed if(TimerDiffTicks(InterruptTimer) > 15820) //about 120 times a second { sync_before_read((void*)INT_BASE, 0x80); if((read32(RSW_INT) & 2) || (read32(DI_INT) & 4) || (read32(SI_INT) & 8) || (read32(EXI_INT) & 0x10)) write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq InterruptTimer = read32(HW_TIMER); } #ifdef PATCHALL if (EXI_IRQ == true) { if(EXICheckTimer()) EXIInterrupt(); } #endif if (SI_IRQ != 0) { if ((TimerDiffTicks(PADTimer) > 7910) || (SI_IRQ & 0x2)) // about 240 times a second { SIInterrupt(); PADTimer = read32(HW_TIMER); } } if(DI_IRQ == true) { if(DiscCheckAsync()) DIInterrupt(); else udelay(200); //let the driver load data } else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */ { if(TimerDiffSeconds(Now) > 2) /* after 3 second earliest */ { EXISaveCard(); SaveCard = false; } } else if(UseUSB && TimerDiffSeconds(USBReadTimer) > 149) /* Read random sector every 2 mins 30 secs */ { DIFinishAsync(); //if something is still running DI_CallbackMsg.result = -1; sync_after_write(&DI_CallbackMsg, 0x20); IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg ); DIFinishAsync(); USBReadTimer = read32(HW_TIMER); } udelay(10); //wait for other threads //Baten Kaitos save hax /*if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } }*/ if( WaitForRealDisc == 1 ) { if(RealDI_NewDisc()) { DiscChangeTimer = read32(HW_TIMER); WaitForRealDisc = 2; //do another flush round, safety! } } else if( WaitForRealDisc == 2 ) { if(TimerDiffSeconds(DiscChangeTimer)) { //identify disc after flushing everything RealDI_Identify(false); //clear our fake regs again sync_before_read((void*)DI_BASE, 0x40); write32(DI_IMM, 0); write32(DI_COVER, 0); sync_after_write((void*)DI_BASE, 0x40); //mask and clear interrupts write32( DIP_STATUS, 0x54 ); //disable cover irq which DIP enabled write32( DIP_COVER, 4 ); DIInterrupt(); WaitForRealDisc = 0; } } if ( DiscChangeIRQ == 1 ) { DiscChangeTimer = read32(HW_TIMER); DiscChangeIRQ = 2; } else if ( DiscChangeIRQ == 2 ) { if ( TimerDiffSeconds(DiscChangeTimer) > 2 ) { DIInterrupt(); DiscChangeIRQ = 0; } } _ahbMemFlush(1); DIUpdateRegisters(); #ifdef PATCHALL EXIUpdateRegistersNEW(); GCAMUpdateRegisters(); BTUpdateRegisters(); HIDUpdateRegisters(0); if(DisableSIPatch == 0) SIUpdateRegisters(); #endif StreamUpdateRegisters(); CheckOSReport(); if(EXICheckCard()) { Now = read32(HW_TIMER); SaveCard = true; } sync_before_read((void*)RESET_STATUS, 0x20); vu32 reset_status = read32(RESET_STATUS); if (reset_status == 0x1DEA) { write32(RESET_STATUS, 0); sync_after_write((void*)RESET_STATUS, 0x20); DIFinishAsync(); break; } if (reset_status == 0x3DEA) { if (Reset == 0) { dbgprintf("Fake Reset IRQ\n"); write32( RSW_INT, 0x2 ); // Reset irq sync_after_write( (void*)RSW_INT, 0x20 ); write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq Reset = 1; } } else if (Reset == 1) { write32( RSW_INT, 0x10000 ); // send pressed sync_after_write( (void*)RSW_INT, 0x20 ); ResetTimer = read32(HW_TIMER); Reset = 2; } /* The cleanup is not connected to the button press */ if (Reset == 2) { if (TimerDiffTicks(ResetTimer) > 949219) //free after half a second { write32( RSW_INT, 0 ); // done, clear sync_after_write( (void*)RSW_INT, 0x20 ); Reset = 0; } } if(reset_status == 0x4DEA) PatchGame(); if(reset_status == 0x5DEA) { SetIPL(); PatchGame(); } if(reset_status == 0x6DEA) { SetIPL_TRI(); write32(RESET_STATUS, 0); sync_after_write((void*)RESET_STATUS, 0x20); } if(read32(HW_GPIO_IN) & GPIO_POWER) { DIFinishAsync(); #ifdef PATCHALL BTE_Shutdown(); #endif Shutdown(); } //sync_before_read( (void*)0x1860, 0x20 ); //if( read32(0x1860) != 0xdeadbeef ) //{ // if( read32(0x1860) != 0 ) // { // dbgprintf( (char*)(P2C(read32(0x1860))), // (char*)(P2C(read32(0x1864))), // (char*)(P2C(read32(0x1868))), // (char*)(P2C(read32(0x186C))), // (char*)(P2C(read32(0x1870))), // (char*)(P2C(read32(0x1874))) // ); // } // write32(0x1860, 0xdeadbeef); // sync_after_write( (void*)0x1860, 0x20 ); //} cc_ahbMemFlush(1); } //if( UseHID ) HIDClose(); IOS_Close(DI_Handle); //close game thread_cancel(DI_Thread, 0); DIUnregister(); /* reset time */ while(1) { sync_before_read( (void*)RESET_STATUS, 0x20 ); if(read32(RESET_STATUS) == 0x2DEA) break; wait_for_ppc(1); } if( ConfigGetConfig(NIN_CFG_LED) ) clear32(HW_GPIO_OUT, GPIO_SLOT_LED); if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) ) EXIShutdown(); if (ConfigGetConfig(NIN_CFG_LOG)) closeLog(); #ifdef PATCHALL BTE_Shutdown(); #endif //unmount FAT device free(fatfs); fatfs = NULL; f_mount(NULL, fatDevName, 1); if(UseUSB) USBStorage_Shutdown(); else SDHCShutdown(); //make sure we set that back to the original write32(HW_PPCSPEED, ori_ppcspeed); if(IsWiiU) { write32(0xd8006a0, ori_widesetting); mask32(0xd8006a8, 0, 2); } DoIOSBoot: sync_before_read((void*)0x13003000, 0x420); IOSBoot((char*)0x13003020, 0, read32(0x13003000)); return 0; }
void videoInit() { // Blank screen for faster loading REG_DISPCNT = DCNT_BLANK; // Completely clear VRAM memset16(vid_mem, 0x0000, 49152); // BACKGROUND SETUP // // Set background 0 control register // -Render this BG on bottom // -Tile indexing starts in charblock 0 // -Screen-entry indexing starts in charblock 3 / screenblock 24 // -4 bits per pixel // -512 x 512 pixels - 32 x 32 tiles - 1 x 1 screenblocks REG_BG0CNT = BG_PRIO(3) | BG_CBB(0) | BG_SBB(24) | BG_4BPP | BG_REG_32x32; // Set background 2 control register - Bottom text screen // -Render this BG on top // -Tile indexing starts in charblock 0 // -Screen-entry indexing starts in charblock 3 / screenblock 29 // -4 bits per pixel // -256 x 256 pixels - 32 x 32 tiles - 1 x 1 screenblocks REG_BG2CNT = BG_PRIO(1) | BG_CBB(0) | BG_SBB(29) | BG_4BPP | BG_REG_32x32; // Set background 3 control register - Top Text Screen // -Render this BG on top // -Tile indexing starts in charblock 0 // -Screen-entry indexing starts in charblock 3 / screenblock 28 // -4 bits per pixel // -256 x 256 pixels - 32 x 32 tiles - 1 x 1 screenblocks REG_BG3CNT = BG_PRIO(0) | BG_CBB(0) | BG_SBB(28) | BG_4BPP | BG_REG_32x32; // Load background palette memcpy16(&pal_bg_mem[0], g_bgPal, g_bgPalLen >> 1); // Load background tiles // Load Font tiles memcpy16(&tile_mem[0][g_galaxulonFont_TilesPos], g_galaxulonFont_Tiles, g_galaxulonFont_TilesLen >> 1); // Load other BG tiles memcpy16(&tile_mem[0][g_blankBG_TilesPos], g_blankBG_Tiles, g_blankBG_TilesLen >> 1); memcpy16(&tile_mem[0][g_assertTile_TilesPos], g_assertTile_Tiles, g_assertTile_TilesLen >> 1); memcpy16(&tile_mem[0][g_demo_starsTilesPos], g_demo_starsTiles, g_demo_starsTilesLen >> 1); // Clear Background screenmaps - set the four background screenblocks memset32(&se_mem[24], 0x00000000, (SBB_SIZE/4)); // OAM SETUP // // Load OAM palette memcpy16(pal_obj_mem, g_spritePal, g_spritePalLen >> 1); // Load OAM tiles // Init Player sprite memcpy16(&tile_mem_obj[0][g_playerSpriteTilesPos], g_playerSpriteTiles, g_playerSpriteTilesLen >> 1); // Init bullet sprites memcpy16(&tile_mem_obj[0][g_bulletSpriteTilesPos], g_bulletSpriteTiles, g_bulletSpriteTilesLen >> 1); memcpy16(&tile_mem_obj[0][g_missileSpriteTilesPos], g_missileSpriteTiles, g_missileSpriteTilesLen >> 1); // Init display sprites memcpy16(&tile_mem_obj[0][g_bullet_selection1TilesPos], g_bullet_selection1Tiles, g_bullet_selection1TilesLen >> 1); memcpy16(&tile_mem_obj[0][g_bullet_selection2TilesPos], g_bullet_selection2Tiles, g_bullet_selection2TilesLen >> 1); // Init enemy sprites memcpy16(&tile_mem_obj[0][g_jellyfishTilesPos], g_jellyfishTiles, g_jellyfishTilesLen >> 1); memcpy16(&tile_mem_obj[0][g_mineTilesPos], g_mineTiles, g_mineTilesLen >> 1); memcpy16(&tile_mem_obj[0][g_sharkTilesPos], g_sharkTiles, g_sharkTilesLen >> 1); memcpy16(&tile_mem_obj[0][g_squidTilesPos], g_squidTiles, g_squidTilesLen >> 1); memcpy16(&tile_mem_obj[0][g_crabTilesPos], g_crabTiles, g_crabTilesLen >> 1); // Init upgrade sprites memcpy16(&tile_mem_obj[0][g_extraLife_TilesPos], g_extraLife_Tiles, g_extraLife_TilesLen >> 1); memcpy16(&tile_mem_obj[0][g_extraBomb_TilesPos], g_extraBomb_Tiles, g_extraBomb_TilesLen >> 1); memcpy16(&tile_mem_obj[0][g_primaryFireUp_TilesPos], g_primaryFireUp_Tiles, g_primaryFireUp_TilesLen >> 1); memcpy16(&tile_mem_obj[0][g_secondFireUp_TilesPos], g_secondFireUp_Tiles, g_secondFireUp_TilesLen >> 1); memcpy16(&tile_mem_obj[0][g_shield_TilesPos], g_shield_Tiles, g_shield_TilesLen >> 1); // Load Title screen logo memcpy16(&tile_mem_obj[0][g_galaxulon_titleTilesPos1], g_galaxulon_titleTiles, g_galaxulon_titleTilesLen >> 1); // Clear OAM oam_init(oam_mem, 128); // Setup Display Control Register // -Video mode 0 - tiled // -BG 0, BG 2, and BG 3 enabled // -Enable sprites // -1D sprite-mapping mode REG_DISPCNT = DCNT_MODE0 | DCNT_OBJ_1D | DCNT_BG0 | DCNT_BG2 | DCNT_BG3 | DCNT_OBJ; }
/* 888RLE image format: [count(2 bytes), rle(3 bytes)] */ int load_565rle_image(char *filename) { struct fb_info *info; int fd, count, err = 0; unsigned max; unsigned char *data, *ptr; unsigned int *bits; unsigned int pixel; info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; goto err_logo_free_data; } max = fb_width(info) * fb_height(info); ptr = data; bits = (unsigned int *)(info->screen_base); while (count > 4) { unsigned n = ptr[0] | ptr[1] << 8; if (n > max) break; pixel = (0xff<<24)|(ptr[4]<<16)|(ptr[3]<<8)|ptr[2]; memset32(bits, pixel, n << 1); bits += n; max -= n; ptr += 5; count -= 5; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
void GCAMCommand( char *DataIn, char *DataOut ) { u32 i = 0; DataPos = 0; resp = 0; u32 CMDLen = DataIn[++DataPos]; DataPos++; // dbgprintf("GC-AM:Length:%u\n", CMDLen ); memset32( res, 0, 0x80 ); res[resp++] = 1; res[resp++] = 1; while( DataPos <= CMDLen ) { // dbgprintf("%02X,", DataIn[DataPos] ); switch( DataIn[DataPos++] ) { /* No reply */ case 0x05: dbgprintf( "GC-AM: CMD 05 (%02X,%02X,%02X,%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1], DataIn[DataPos+2], DataIn[DataPos+3], DataIn[DataPos+4] ); DataPos += 5; break; /* No reply */ case 0x08: dbgprintf( "GC-AM: CMD 08 (%02X,%02X,%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1], DataIn[DataPos+2], DataIn[DataPos+3] ); DataPos += 4; break; /* 2 bytes out */ case 0x10: { res[resp++] = 0x10; res[resp++] = 0x02; d10_0 = 0xFF; //u32 buttons = read32(TRIButtons);//*(vu32*)0x0d806404; //u32 sticks = *(vu32*)0x0d806408; // Service button //if( buttons & PAD_BUTTON_X ) // d10_0 &= ~0x80; // Test button //if( buttons & PAD_TRIGGER_Z ) // d10_0 &= ~0x40; //Switch Status res[resp++] = d10_0; //Reset Status res[resp++] = d10_1; //dbgprintf("ReadStatus and Switches(%02X %02X,%02X)\n", DataIn[DataPos], d10_0, d10_1 ); DataPos += DataIn[DataPos] + 1; } break; case 0x11: { dbgprintf("GetSerial(%02X)\n", DataIn[DataPos] ); res[resp++] = 0x11; res[resp++] = 0x10; memcpy( res + resp, "AADE01A28834511", 16 ); resp += 0x10; DataPos += DataIn[DataPos] + 1; } break; /* No reply */ case 0x12: { dbgprintf("Unknown(12) (%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1] ); DataPos += DataIn[DataPos] + 1; } break; /* 4 half-words out */ // case 0x14: /* 2 bytes out */ case 0x15: { dbgprintf("GetFirmware Version(%02X)\n", DataIn[DataPos++] ); res[resp++] = 0x15; res[resp++] = 0x02; // FIRM VERSION res[resp++] = 0x00; res[resp++] = 0x29; } break; /* 2 bytes out */ case 0x16: { dbgprintf("GetFPGA Version(%02X)\n", DataIn[DataPos++] ); res[resp++] = 0x16; res[resp++] = 0x02; // FPGAVERSION res[resp++] = 0x07; res[resp++] = 0x06; } break; case 0x1F: { dbgprintf("GetRegion(%02X,%02X,%02X,%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1], DataIn[DataPos+2], DataIn[DataPos+3], DataIn[DataPos+4] ); unsigned char string[0x14]; switch(SystemRegion) { case REGION_USA: memcpy(string, "\x00\x00\x30\x00" "\x02\xfd\x00\x00" // USA "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 0x14); break; case REGION_EXPORT: memcpy(string, "\x00\x00\x30\x00" "\x03\xfc\x00\x00" // export "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 0x14); break; default: memcpy(string, "\x00\x00\x30\x00" "\x01\xfe\x00\x00" // JAPAN "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 0x14); break; } res[resp++] = 0x1F; res[resp++] = 0x14; for (i=0; i<0x14; ++i) res[resp++] = string[i]; DataPos += 5; } break; /* No reply */ case 0x21: dbgprintf( "GC-AM: CMD 21 (%02X,%02X,%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1], DataIn[DataPos+2], DataIn[DataPos+3] ); DataPos += 4; break; /* No reply */ case 0x22: dbgprintf( "GC-AM: CMD 22 (%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1], DataIn[DataPos+2], DataIn[DataPos+3], DataIn[DataPos+4], DataIn[DataPos+5], DataIn[DataPos+6], DataIn[DataPos+7] ); DataPos += DataIn[DataPos] + 1; break; /* 3 byte out */ //case 0x23: /* flexible length out */ case 0x31: if(DataIn[DataPos]) { // All commands are OR'd with 0x80 // Last byte (ptr(5)) is checksum which we don't care about u32 cmd = (DataIn[DataPos+1]^0x80) << 24; cmd|= DataIn[DataPos+2] << 16; cmd|= DataIn[DataPos+3] << 8; //dbgprintf( "GC-AM: CMD 31 (SERIAL) (%08X)\n", cmd ); // Serial - Wheel if( cmd == 0x7FFFFF00 ) { res[resp++] = 0x31; res[resp++] = 0x03; res[resp++] = 'C'; res[resp++] = '0'; if( STRInit == 0 ) { res[resp++] = '1'; STRInit = 1; } else { res[resp++] = '6'; } } } DataPos += DataIn[DataPos] + 1; break; // CARD-Interface case 0x32: { if( !DataIn[DataPos] ) { res[resp++] = 0x32; res[resp++] = 0x00; // len } else { dbgprintf("CARD(32) (%02X) (", DataIn[DataPos] ); for( i=0; i < DataIn[DataPos]; ++i ) { dbgprintf("%02X,", DataIn[DataPos+i+1] ); } dbgprintf(")\n"); GCAMCARDCommand( DataIn, DataOut ); } DataPos += DataIn[DataPos] + 1; } break; case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47: case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: { JVSIOCommand( DataIn, DataOut ); } break; /* No reply */ case 0x60: { dbgprintf("Unknown(60) (%02X,%02X,%02X)\n", DataIn[DataPos], DataIn[DataPos+1], DataIn[DataPos+2] ); DataPos += DataIn[DataPos] + 1; } break; case 0x00: { } break; default: { dbgprintf("GC-AM:Unhandled CMD:0x%02X DataPos:0x%02X\n", DataIn[DataPos-1], DataPos-1 ); hexdump( DataIn, 0x80 ); Shutdown(); } break; } } res[1] = resp - 2; u32 chk=0; for( i=0; i < 0x7F; i++) chk+=res[i]; res[0x7F] = ~(chk & 0xFF); //Check checksum (???) //chk = 0; //for( i=0; i < 0x80; i++) // chk+=res[i]; memcpy( DataOut, res, 0x80 ); }