/******************************************************************************************* * @函数名:SDRAM_Init() * @参数 :void * @返回值:void * @描述 :SDRAM管脚配置函数,在使用SDRAM前先调用 *********************************************************************************************/ void lpc1788_SDRAM_Init( void ) { volatile uint32_t i; volatile unsigned long Dummy; SDRAM_GPIO_Config(); LPC_SC->PCONP |= 0x00000800; /*Init SDRAM controller*/ LPC_SC->EMCDLYCTL |= (8<<0); /*Set data read delay*/ LPC_SC->EMCDLYCTL |=(8<<8); LPC_SC->EMCDLYCTL |= (0x08 <<16); LPC_EMC->Control =1; LPC_EMC->DynamicReadConfig = 1; LPC_EMC->DynamicRasCas0 = 0; LPC_EMC->DynamicRasCas0 |=(3<<8); LPC_EMC->DynamicRasCas0 |= (3<<0); LPC_EMC->DynamicRP = P2C(SDRAM_TRP); LPC_EMC->DynamicRAS = P2C(SDRAM_TRAS); LPC_EMC->DynamicSREX = P2C(SDRAM_TXSR); LPC_EMC->DynamicAPR = SDRAM_TAPR; LPC_EMC->DynamicDAL = SDRAM_TDAL+P2C(SDRAM_TRP); LPC_EMC->DynamicWR = SDRAM_TWR; LPC_EMC->DynamicRC = P2C(SDRAM_TRC); LPC_EMC->DynamicRFC = P2C(SDRAM_TRFC); LPC_EMC->DynamicXSR = P2C(SDRAM_TXSR); LPC_EMC->DynamicRRD = P2C(SDRAM_TRRD); LPC_EMC->DynamicMRD = SDRAM_TMRD; #if SDRAM_TYPE==SDRAM_32BIT // 13 row, 9 - col, SDRAM LPC_EMC->DynamicConfig0 = 0x0004680; // JEDEC General SDRAM Initialization Sequence // DELAY to allow power and clocks to stabilize ~100 us // NOP #else LPC_EMC->DynamicConfig0 = 0x000680; #endif LPC_EMC->DynamicControl = 0x0183; for(i= 200*30; i;i--); // PALL LPC_EMC->DynamicControl = 0x0103; LPC_EMC->DynamicRefresh = 2; for(i= 256; i; --i); // > 128 clk LPC_EMC->DynamicRefresh = P2C(SDRAM_REFRESH) >> 4; // COMM LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */ #if SDRAM_TYPE==SDRAM_32BIT Dummy = *((volatile uint32_t *)(SDRAM_BASE| (0x32<<13))); #else Dummy = *((volatile uint32_t *)(SDRAM_BASE| (0x33<<12))); #endif // NORM LPC_EMC->DynamicControl = 0x0000; LPC_EMC->DynamicConfig0 |=(1<<19); for(i = 100000; i;i--); }
void * suba_realloc(struct allocator *suba, void *ptr, size_t size) { struct cell *c; void *p; if (ptr == NULL) { if ((p = suba_alloc(suba, size, 0)) == NULL) { AMSG(""); } return p; } if (size == 0) { suba_free(suba, ptr); return NULL; } c = P2C(ptr); if (c->size < size || (c->size - ALIGN(size)) > suba->mincell) { p = suba_alloc(suba, size, 0); } else { return ptr; } if (p) { memcpy(p, ptr, size); suba_free(suba, ptr); } return p; }
// External memory initialization static void platform_setup_extmem() { #ifdef ELUA_BOARD_ELUAPUC volatile unsigned int i; volatile DWORD wtemp; EMC_CTRL = 0x00000001; /*Disable Address mirror*/ PCONP |= 0x00000800; /* Turn On EMC PCLK */ PINSEL4 = 0x50000000; PINSEL5 = 0x05050555; PINSEL6 = 0x55555555; PINSEL8 = 0x55555555; PINSEL9 = 0x50555555; EMC_DYN_RP = P2C(SDRAM_TRP); EMC_DYN_RAS = P2C(SDRAM_TRAS); EMC_DYN_SREX = P2C(SDRAM_TXSR); EMC_DYN_APR = SDRAM_TAPR; EMC_DYN_DAL = SDRAM_TDAL ; EMC_DYN_WR = SDRAM_TWR; EMC_DYN_RC = P2C(SDRAM_TRC); EMC_DYN_RFC = P2C(SDRAM_TRFC); EMC_DYN_XSR = P2C(SDRAM_TXSR); EMC_DYN_RRD = P2C(SDRAM_TRRD); EMC_DYN_MRD = SDRAM_TMRD; EMC_DYN_RD_CFG=1;//Configures the dynamic memory read strategy(Command delayed strategy) /* Default setting, RAS latency 3 CCLKs, CAS latenty 3 CCLKs. */ EMC_DYN_RASCAS0 = 0x00000303; // RAS delay = 3, CAS delay = 3 EMC_DYN_CFG0 = 0x00000280; //16 bit external bus, 64 MB (4Mx16), 4 banks, row length = 12, column length = 8 for( i = 0; i < 40000; i ++ ); // JEDEC General SDRAM Initialization Sequence // DELAY to allow power and clocks to stabilize ~100 us // NOP EMC_DYN_CTRL = 0x0183; //Issue SDRAM NOP (no operation) command ; CLKOUT runs continuously;All clock enables are driven HIGH continuously for( i = 0; i < 80000; i ++ ); EMC_DYN_CTRL = 0x00000103; //Issue SDRAM PALL (precharge all) command. EMC_DYN_RFSH = 1; //Indicates 1X16 CCLKs between SDRAM refresh cycles. for(i = 0; i < 0x40; i ++); //EMC_DYN_RFSH = P2C(SDRAM_REFRESH) >> 4; // //Indicates ?? CCLKs between SDRAM refresh cycles. EMC_DYN_RFSH = 70; EMC_DYN_CTRL = 0x00000083; wtemp = *(volatile DWORD *)(SDRAM_CS0_BASE | (0x33 << 11)); /* 8 burst, 3 CAS latency */ // modified from AN EMC_DYN_CTRL = 0x0000; //Issue SDRAM norm command ; CLKOUT stop;All clock enables low EMC_DYN_CFG0|=0x80000; //Buffer enabled for accesses to DCS0 chip for(i = 200*10; i;i--); #endif }
static gboolean node_build_string (GNode *node, gpointer data) { gchar **p = data; gchar *string; gchar c[2] = "_"; c[0] = P2C (node->data); string = g_strconcat (*p ? *p : "", c, NULL); g_free (*p); *p = string; return FALSE; }
int suba_free(void *suba0, void *ptr) { struct allocator *suba = suba0; struct cell *c1, *c2, *c3; ref_t ref; int j1, j2; if (!ptr) return 0; if (!suba_ref(suba, ptr)) { PMNO(errno = EFAULT); return -1; } /* splice the cell back into the list */ c1 = SADR(suba, suba->tail); c2 = P2C(ptr); if (c2->size > suba->max_free || (ref = suba_ref(suba, c2)) == 0) { PMNF(errno = EINVAL, ": %p: %d", ptr, c2->size); return -1; } // CHDK counters suba->allocated_size -= POFF + c2->size; suba->allocated_count--; // old suba counter // suba->free_total += POFF + c2->size; /* c2->stk[0] = NULL; suba_print_cell(suba, " FREE", c2); */ if (c2 > c1) { /* append to end of list */ if (ISADJ(c1,c2)) { /* join with last cell */ c1->size += POFF + c2->size; return 0; } c2->next = c1->next; suba->tail = c1->next = ref; return 0; } while (c1->next < ref) { /* find insertion point */ if (c1->next < POFF) { PMNF(errno = EINVAL, ": next ref corrupted: %d", c1->next); return -1; } c1 = SADR(suba, c1->next); } c3 = SADR(suba, c1->next); j1 = ISADJ(c1,c2); /* c1 and c2 need to be joined */ j2 = ISADJ(c2,c3); /* c2 and c3 need to be joined */ if (j1) { if (j2) { /* splice all three cells together */ if (SREF(suba, c3) == suba->tail) { suba->tail = SREF(suba, c1); } c1->next = c3->next; c1->size += POFF + c3->size; } c1->size += POFF + c2->size; } else { if (j2) { if (SREF(suba, c3) == suba->tail) { suba->tail = ref; } c2->next = c3->next == SREF(suba, c3) ? ref : c3->next; c2->size += POFF + c3->size; } else { c2->next = c1->next; } c1->next = ref; } return 0; }
static void g_node_test (void) { GNode *root; GNode *node; GNode *node_B; GNode *node_D; GNode *node_F; GNode *node_G; GNode *node_J; guint i; gchar *tstring; failed = FALSE; root = g_node_new (C2P ('A')); TEST (NULL, g_node_depth (root) == 1 && g_node_max_height (root) == 1); node_B = g_node_new (C2P ('B')); g_node_append (root, node_B); TEST (NULL, root->children == node_B); g_node_append_data (node_B, C2P ('E')); g_node_prepend_data (node_B, C2P ('C')); node_D = g_node_new (C2P ('D')); g_node_insert (node_B, 1, node_D); node_F = g_node_new (C2P ('F')); g_node_append (root, node_F); TEST (NULL, root->children->next == node_F); node_G = g_node_new (C2P ('G')); g_node_append (node_F, node_G); node_J = g_node_new (C2P ('J')); g_node_prepend (node_G, node_J); g_node_insert (node_G, 42, g_node_new (C2P ('K'))); g_node_insert_data (node_G, 0, C2P ('H')); g_node_insert (node_G, 1, g_node_new (C2P ('I'))); TEST (NULL, g_node_depth (root) == 1); TEST (NULL, g_node_max_height (root) == 4); TEST (NULL, g_node_depth (node_G->children->next) == 4); TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_LEAFS) == 7); TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_NON_LEAFS) == 4); TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == 11); TEST (NULL, g_node_max_height (node_F) == 3); TEST (NULL, g_node_n_children (node_G) == 4); TEST (NULL, g_node_find_child (root, G_TRAVERSE_ALL, C2P ('F')) == node_F); TEST (NULL, g_node_find (root, G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, C2P ('I')) == NULL); TEST (NULL, g_node_find (root, G_IN_ORDER, G_TRAVERSE_LEAFS, C2P ('J')) == node_J); for (i = 0; i < g_node_n_children (node_B); i++) { node = g_node_nth_child (node_B, i); TEST (NULL, P2C (node->data) == ('C' + i)); } for (i = 0; i < g_node_n_children (node_G); i++) TEST (NULL, g_node_child_position (node_G, g_node_nth_child (node_G, i)) == i); /* we have built: A * / \ * B F * / | \ \ * C D E G * / /\ \ * H I J K * * for in-order traversal, 'G' is considered to be the "left" * child of 'F', which will cause 'F' to be the last node visited. */ tstring = NULL; g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "ABCDEFGHIJK") == 0); g_free (tstring); tstring = NULL; g_node_traverse (root, G_POST_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "CDEBHIJKGFA") == 0); g_free (tstring); tstring = NULL; g_node_traverse (root, G_IN_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "CBDEAHGIJKF") == 0); g_free (tstring); tstring = NULL; g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "ABFCDEGHIJK") == 0); g_free (tstring); tstring = NULL; g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_LEAFS, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "CDEHIJK") == 0); g_free (tstring); tstring = NULL; g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_NON_LEAFS, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "ABFG") == 0); g_free (tstring); tstring = NULL; g_node_reverse_children (node_B); g_node_reverse_children (node_G); g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "ABFEDCGKJIH") == 0); g_free (tstring); tstring = NULL; g_node_append (node_D, g_node_new (C2P ('L'))); g_node_append (node_D, g_node_new (C2P ('M'))); g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring); TEST (tstring, strcmp (tstring, "ABFEDCGLMKJIH") == 0); g_free (tstring); tstring = NULL; g_node_destroy (root); /* allocation tests */ root = g_node_new (NULL); node = root; for (i = 0; i < 2048; i++) { g_node_append (node, g_node_new (NULL)); if ((i%5) == 4) node = node->children->next; } TEST (NULL, g_node_max_height (root) > 100); TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == 1 + 2048); g_node_destroy (root); if (failed) exit(1); }
/*********************************************************************//** * @brief Initialize external SDRAM memory Micron MT48LC8M32LFB5 * 256Mbit(8M x 32) * @param[in] None * @return None **********************************************************************/ void SDRAMInit( void ) { volatile uint32_t i; volatile unsigned long Dummy; // PINSEL_ConfigPin(2,14,1); /* P2.14 - /EMC_CS2 */ // PINSEL_ConfigPin(2,15,1); /* P2.15 - /EMC_CS3 */ PINSEL_ConfigPin(2,16,1); /* P2.16 - /EMC_CAS */ PINSEL_ConfigPin(2,17,1); /* P2.17 - /EMC_RAS */ PINSEL_ConfigPin(2,18,1); /* P2.18 - EMC_CLK[0] */ // PINSEL_ConfigPin(2,19,1); /* P2.19 - EMC_CLK[1] */ PINSEL_ConfigPin(2,20,1); /* P2.20 - EMC_DYCS0 */ // PINSEL_ConfigPin(2,21,1); /* P2.21 - EMC_DYCS1 */ // PINSEL_ConfigPin(2,22,1); /* P2.22 - EMC_DYCS2 */ // PINSEL_ConfigPin(2,23,1); /* P2.23 - EMC_DYCS3 */ PINSEL_ConfigPin(2,24,1); /* P2.24 - EMC_CKE0 */ // PINSEL_ConfigPin(2,25,1); /* P2.25 - EMC_CKE1 */ // PINSEL_ConfigPin(2,26,1); /* P2.26 - EMC_CKE2 */ // PINSEL_ConfigPin(2,27,1); /* P2.27 - EMC_CKE3 */ PINSEL_ConfigPin(2,28,1); /* P2.28 - EMC_DQM0 */ PINSEL_ConfigPin(2,29,1); /* P2.29 - EMC_DQM1 */ // PINSEL_ConfigPin(2,30,1); /* P2.30 - EMC_DQM2 */ // PINSEL_ConfigPin(2,31,1); /* P2.31 - EMC_DQM3 */ // PINSEL_ConfigPin(4,24,1); /* P4.24 - /EMC_OE */ PINSEL_ConfigPin(4,25,1); /* P4.25 - /EMC_WE */ // PINSEL_ConfigPin(4,30,1); /* P4.30 - /EMC_CS0 */ // PINSEL_ConfigPin(4,31,1); /* P4.31 - /EMC_CS1 */ for(i = 0; i < 16; i++) { PINSEL_ConfigPin(3,i,1); /* P3.0-P3.15 - EMC_D[0-15] */ } for(i = 0; i < 15; i++) { PINSEL_ConfigPin(4,i,1); /* P4.0-P4.14 - EMC_A[0-14] */ } // EMC_Init(); // Init SDRAM controller LPC_SC->PCONP |= 0x00000800; /*Init SDRAM controller*/ LPC_SC->EMCDLYCTL |= (8<<0); /*Set data read delay*/ LPC_SC->EMCDLYCTL |=(8<<8); LPC_SC->EMCDLYCTL |= (0x08 <<16); LPC_EMC->Control =1; LPC_EMC->DynamicReadConfig = 1; LPC_EMC->DynamicRasCas0 = 0; LPC_EMC->DynamicRasCas0 |=(3<<8); LPC_EMC->DynamicRasCas0 |= (3<<0); LPC_EMC->DynamicRP = P2C(SDRAM_TRP); LPC_EMC->DynamicRAS = P2C(SDRAM_TRAS); LPC_EMC->DynamicSREX = P2C(SDRAM_TXSR); LPC_EMC->DynamicAPR = SDRAM_TAPR; LPC_EMC->DynamicDAL = SDRAM_TDAL+P2C(SDRAM_TRP); LPC_EMC->DynamicWR = SDRAM_TWR; LPC_EMC->DynamicRC = P2C(SDRAM_TRC); LPC_EMC->DynamicRFC = P2C(SDRAM_TRFC); LPC_EMC->DynamicXSR = P2C(SDRAM_TXSR); LPC_EMC->DynamicRRD = P2C(SDRAM_TRRD); LPC_EMC->DynamicMRD = SDRAM_TMRD; // SDRAM LPC_EMC->DynamicConfig0 = 0x0000680; // JEDEC General SDRAM Initialization Sequence // DELAY to allow power and clocks to stabilize ~100 us // NOP LPC_EMC->DynamicControl = 0x0183; for(i= 200*30; i;i--); // PALL LPC_EMC->DynamicControl = 0x0103; LPC_EMC->DynamicRefresh = 2; for(i= 256; i; --i); // > 128 clk LPC_EMC->DynamicRefresh = P2C(SDRAM_REFRESH) >> 4; // COMM LPC_EMC->DynamicControl = 0x00000083; /* Issue MODE command */ Dummy = *((volatile uint32_t *)(SDRAM_BASE_ADDR | (0x33<<12))); // NORM LPC_EMC->DynamicControl = 0x0000; LPC_EMC->DynamicConfig0 |=(1<<19); for(i = 100000; i;i--); }
void TRIBackupSettings() { if(TRISettingsName == (char*)0 || TRISettingsLoc == 0 || TRISettingsSize == 0) return; void *GameSettingsLoc = (TRIGame == TRI_AX || TRIGame == TRI_YAK) ? (void*)TRISettingsLoc : (void*)P2C(read32(TRISettingsLoc)); sync_before_read_align32(GameSettingsLoc, TRISettingsSize); sync_before_read_align32(OUR_SETTINGS_LOC, TRISettingsSize); if((memcmp(OUR_SETTINGS_LOC, GameSettingsLoc, TRISettingsSize) != 0) && (memcmp(GameSettingsLoc, "SB", 2) == 0)) { dbgprintf("TRI:Writing Settings\r\n"); memcpy(OUR_SETTINGS_LOC, GameSettingsLoc, TRISettingsSize); FIL backup; if(f_open_char(&backup, TRISettingsName, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { u32 wrote; f_write(&backup, OUR_SETTINGS_LOC, TRISettingsSize, &wrote); f_close(&backup); } sync_after_write_align32(OUR_SETTINGS_LOC, TRISettingsSize); TRI_BackupAvailable = 1; } }
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 ); } }
u32 DIUpdateRegisters( void ) { u32 read,i; static u32 PatchState = 0; static u32 DOLReadSize= 0; if( read32(DI_CONTROL) != 0xdeadbeef ) { write32( DI_SCONTROL, read32(DI_CONTROL) & 3 ); clear32( DI_SSTATUS, 0x14 ); write32( DI_CONTROL, 0xdeadbeef ); if( read32(DI_SCONTROL) & 1 ) { if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) ) set32( HW_GPIO_OUT, 1<<5 ); if( read32(DI_CMD_0) != 0xdeadbeef ) { write32( DI_SCMD_0, read32(DI_CMD_0) ); write32( DI_CMD_0, 0xdeadbeef ); } if( read32(DI_CMD_1) != 0xdeadbeef ) { write32( DI_SCMD_1, read32(DI_CMD_1) ); write32( DI_CMD_1, 0xdeadbeef ); } if( read32(DI_CMD_2) != 0xdeadbeef ) { write32( DI_SCMD_2, read32(DI_CMD_2) ); write32( DI_CMD_2, 0xdeadbeef ); } if( read32(DI_DMA_ADR) != 0xdeadbeef ) { write32( DI_SDMA_ADR, read32(DI_DMA_ADR) ); write32( DI_DMA_ADR, 0xdeadbeef ); } if( read32(DI_DMA_LEN) != 0xdeadbeef ) { write32( DI_SDMA_LEN, read32(DI_DMA_LEN) ); write32( DI_DMA_LEN, 0xdeadbeef ); } if( read32(DI_IMM) != 0xdeadbeef ) { write32( DI_SIMM, read32(DI_IMM) ); write32( DI_IMM, 0xdeadbeef ); } switch( read32(DI_SCMD_0) >> 24 ) { case 0xA7: case 0xA9: //dbgprintf("DIP:Async!\n"); case 0xA8: { u32 Buffer = P2C(read32(DI_SDMA_ADR)); u32 Length = read32(DI_SCMD_2); u32 Offset = read32(DI_SCMD_1) << 2; // dbgprintf("DIP:DVDRead( 0x%08x, 0x%08x, 0x%08x )\n", Offset, Length, Buffer|0x80000000 ); // udelay(250); if( GameFile.fptr != Offset ) if( f_lseek( &GameFile, Offset ) != FR_OK ) { EXIControl(1); dbgprintf("DIP:Failed to seek to 0x%08x\n", Offset ); while(1); } if( f_read( &GameFile, (char*)Buffer, Length, &read ) != FR_OK ) { EXIControl(1); dbgprintf("DIP:Failed to read from 0x%08x to 0x%08X\n", Offset, Buffer ); while(1); } //if( ((read+31)&(~31)) != Length ) //{ // dbgprintf("DIP:DVDLowRead Offset:%08X Size:%08d Dst:%08X\n", Offset, Length, Buffer ); // dbgprintf("DIP:Failed to read %d bytes, only got %d\n", Length, read ); // break; //} if( (u32)Buffer == 0x01300000 ) { DoPatchesLoader( (char*)(0x01300000), Length ); } if( PatchState == 0 ) { if( Length == 0x100 ) { if( read32( (u32)Buffer ) == 0x100 ) { //quickly calc the size DOLSize = sizeof(dolhdr); dolhdr *dol = (dolhdr*)Buffer; for( i=0; i < 7; ++i ) DOLSize += dol->sizeText[i]; for( i=0; i < 11; ++i ) DOLSize += dol->sizeData[i]; DOLReadSize = sizeof(dolhdr); DOLMinOff=0x81800000; DOLMaxOff=0; for( i=0; i < 7; ++i ) { if( dol->addressText[i] == 0 ) continue; if( DOLMinOff > dol->addressText[i]) DOLMinOff = dol->addressText[i]; if( DOLMaxOff < dol->addressText[i] + dol->sizeText[i] ) DOLMaxOff = dol->addressText[i] + dol->sizeText[i]; } DOLMinOff -= 0x80000000; DOLMaxOff -= 0x80000000; dbgprintf("DIP:DOLSize:%d DOLMinOff:0x%08X DOLMaxOff:0x%08X\n", DOLSize, DOLMinOff, DOLMaxOff ); PatchState = 1; } } else if( read32(Buffer) == 0x7F454C46 ) { if (getfilenamebyoffset(Offset) != NULL) { dbgprintf("DIP:The Game is loading %s\n", getfilenamebyoffset(Offset)); } else { dbgprintf("DIP:The Game is loading some .elf that is not in the fst...\n"); } for (i = ((*(u32 *)0x00000038) & ~0x80000000) + 16; i < 0x01800000; i+=12) // Search the fst for the dvd offset of the .elf file { if (*(u32 *)i == Offset) { DOLSize = *(u32 *)(i+4); DOLReadSize = Length; if( DOLReadSize == DOLSize ) // The .elf is read completely already { dbgprintf("DIP:The .elf is read completely, file size: %u bytes\n", DOLSize); DoPatches( (char*)(Buffer), Length, 0x80000000 ); } else // a part of the .elf is read { PatchState = 2; DOLMinOff=Buffer; DOLMaxOff=Buffer+Length; if (Length <= 4096) // The .elf header is read { ELFNumberOfSections = read16(Buffer+0x2c) -2; // Assume that 2 sections are .bss and .sbss which are not read dbgprintf("DIP:The .elf header is read(%u bytes), .elf file size: %u bytes, number of sections to load: %u\n", Length, DOLSize, ELFNumberOfSections); } else // The .elf is read into a buffer { ELFNumberOfSections = -1; // Make sure that ELFNumberOfSections == 0 does not become true dbgprintf("DIP:The .elf is read into a buffer, read progress: %u/%u bytes\n", Length, DOLSize); } } break; } } } } else if ( PatchState != 0 ) { DOLReadSize += Length; if (PatchState == 2) { ELFNumberOfSections--; // DOLMinOff and DOLMaxOff are optimised when loading .dol files if (DOLMinOff > Buffer) DOLMinOff = Buffer; if (DOLMaxOff < Buffer+Length) DOLMaxOff = Buffer+Length; if (ELFNumberOfSections < 0) { dbgprintf("DIP:.elf read progress: %u/%u bytes\n", DOLReadSize, DOLSize); } else { dbgprintf("DIP:.elf read progress: %u/%u bytes, sections left: %u\n", DOLReadSize, DOLSize, ELFNumberOfSections); } } //dbgprintf("DIP:DOLSize:%d DOLReadSize:%d\n", DOLSize, DOLReadSize ); if( DOLReadSize >= DOLSize || (PatchState == 2 && ELFNumberOfSections == 0)) { DoPatches( (char*)(DOLMinOff), DOLMaxOff-DOLMinOff, 0x80000000 ); PatchState = 0; } } write32( DI_SDMA_LEN, 0 ); while( read32(DI_SCONTROL) & 1 ) clear32( DI_SCONTROL, 1 ); set32( DI_SSTATUS, 0x3A ); if( ConfigGetConfig(DML_CFG_NODISC) ) { write32( 0x0d80000C, (1<<0) | (1<<4) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( 0x0d80000C, (1<<2) ); } else { if( (read32(DI_SCMD_0) >> 24) == 0xA7 ) { write32( 0x0d80000C, (1<<0) | (1<<4) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( 0x0d80000C, (1<<2) ); } } } break; default: { EXIControl(1); dbgprintf("DIP:Unknown CMD:%08X %08X %08X %08X %08X %08X\n", read32(DI_SCMD_0), read32(DI_SCMD_1), read32(DI_SCMD_2), read32(DI_SIMM), read32(DI_SDMA_ADR), read32(DI_SDMA_LEN) ); while(1); } break; } if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) ) clear32( HW_GPIO_OUT, 1<<5 ); return 1; } else {