Exemple #1
0
/*******************************************************************************************
* @函数名: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--);
}
Exemple #2
0
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;
}
Exemple #3
0
// 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
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
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--);
}
Exemple #8
0
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;
	}
}
Exemple #9
0
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 {