예제 #1
0
OSStatus host_platform_spi_transfer( bus_transfer_direction_t dir, uint8_t* buffer, uint16_t buffer_length )
{
    OSStatus result;
    int i;

    for(i=0; i<buffer_length; i++) {
        buffer_temp_32[i] = SPI0_TXCMD | (uint32_t)buffer[i];;
    }
    dmaSPITX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPITX.period, 32);
    dmaSPITX.srcAddr = (uint32_t)buffer_temp_32;
    dmaSPITX.length = buffer_length * 4;
    dmaSPIRX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPIRX.period, 32);
    dmaSPIRX.destAddr = (uint32_t)buffer;
    dmaSPIRX.length = buffer_length;
    
    MCU_CLOCKS_NEEDED();
    SPI0_CS_ENABLE;
    setup_edma_loop(&dmaSPITX);
    setup_edma_loop(&dmaSPIRX);

    EDMA_DRV_StartChannel(dmaSPIRX.dmaCh);
    EDMA_DRV_StartChannel(dmaSPITX.dmaCh);

    result = mico_rtos_get_semaphore( &spi_transfer_finished_semaphore, 100 );
    disable_edma_loop(&dmaSPIRX);
    disable_edma_loop(&dmaSPITX);
    SPI0_CS_DISABLE;
    MCU_CLOCKS_NOT_NEEDED();
    free_align(dmaSPITX.dmaChStcd);
    free_align(dmaSPIRX.dmaChStcd);
    return result;
}
예제 #2
0
파일: heap.c 프로젝트: zrho/Oxygen
uint64_t heap_sbrk(intptr_t increase)
{
    // Acquire lock
    spinlock_acquire(&heap_lock);
    
    // Increase?
    if (increase > 0) {
        // Align
        increase = mem_align((uintptr_t) increase, 0x1000);
        
        // Determine amount of pages
        size_t pages = increase / 0x1000;
        size_t i;
        
        for (i = 0; i < pages; ++i) {
            // Allocate frame
            uintptr_t phys = frame_alloc();
            
            // Map frame
            page_map(
                heap_begin + heap_length,
                phys,
                PG_PRESENT | PG_GLOBAL | PG_WRITABLE);
                
            // Increase length
            heap_length += 0x1000;
        }
        
    // Decrease
    } else if (increase < 0) {
        // Align decrease
        uintptr_t decrease = mem_align((uintptr_t) (-increase), 0x1000);
        
        // Determine amount of pages
        size_t pages = decrease / 0x1000;
        size_t i;
        
        for (i = 0; i < pages; ++i) {
            // Get (virtual) begin address of last page
            uintptr_t virt = heap_begin + heap_length;
            
            // Get physical address
            uintptr_t phys = page_get_physical(virt);
            
            // Unmap page
            page_unmap(virt);
            
            // Decrease length
            heap_length -= 0x1000;
        }
    }
    
    // Release lock
    spinlock_release(&heap_lock);
    
    // Beginning of the heap
    return heap_begin;
}
예제 #3
0
s8 VerifyNandBootInfo ( void )
{
	// path : /shared2/sys/NANDBOOTINFO
	NANDBootInfo *Boot_Info = (NANDBootInfo *)mem_align( 32, sizeof(NANDBootInfo) );
	memset( Boot_Info, 0, sizeof(NANDBootInfo) );

	s32 fd = ISFS_Open("/shared2/sys/NANDBOOTINFO", 1 );
	if(fd < 0)
	{
		mem_free( Boot_Info );
		return -1;
	}
	
	s32 ret = ISFS_Read(fd, Boot_Info, sizeof(NANDBootInfo));
	if(ret != sizeof(NANDBootInfo))
	{
		ISFS_Close(fd);
		mem_free( Boot_Info );
		return -2 ;
	}
	ISFS_Close(fd);

	u8 r = Boot_Info->titletype;
	mem_free( Boot_Info );

	if (r == 8)
	{
		SetBootState(4,132,0,0);
		return 1;
	}
	else
		return 0;
}
예제 #4
0
파일: edma.c 프로젝트: 287631983/MICO
void setup_edma_loop(edma_loop_setup_t *loopSetup)
{
  
#if 0
#if (defined(__ICCARM__) || defined(__CC_ARM))
    loopSetup->dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * loopSetup->period, 32);
#elif defined(__GNUC__)
    loopSetup->dmaChStcd = (edma_software_tcd_t *)memalign(32, 2 * sizeof(edma_software_tcd_t) * loopSetup->period);
#endif
#endif

    loopSetup->dmaChStcd = (edma_software_tcd_t *)(((uint32_t)ptcd + 32)& 0xFFFFFFE0);
    //printf(" eDMA TCD address is %x,  them\r\n", (uint32_t)loopSetup->dmaChStcd);

    memset(loopSetup->dmaChStcd, 0, sizeof(edma_software_tcd_t));

    EDMA_DRV_RequestChannel(loopSetup->dmaChanNum, loopSetup->chSource, loopSetup->dmaCh);

    EDMA_DRV_ConfigLoopTransfer(loopSetup->dmaCh, loopSetup->dmaChStcd, loopSetup->type,
                     loopSetup->srcAddr, loopSetup->destAddr, loopSetup->size,
                     loopSetup->watermark, loopSetup->length, loopSetup->period);

    if(loopSetup->dmaCallBack != NULL)
    {
        EDMA_DRV_InstallCallback(loopSetup->dmaCh, loopSetup->dmaCallBack, loopSetup->dmaCh);
    }
}
예제 #5
0
파일: main.cpp 프로젝트: Estwald/PSDK3v2
int main(int argc,const char *argv[])
{
    s32 ret,i;
    padInfo padinfo;
    padData paddata;
    rsxProgramConst *consts = rsxFragmentProgramGetConsts(fpo);

    initialize();
    ioPadInit(7);

    sphere = createSphere(3.0f,32,32);
    donut = createDonut(3.0f,1.5f,32,32);
    cube = createCube(5.0f);

    rsxConstOffsetTable *co_table = rsxFragmentProgramGetConstOffsetTable(fpo,consts[lightColor_id].index);
    u32 const_addr = (u32)((u64)fp_buffer + co_table->offset[0]);
    setup_shared_buffer(const_addr,(u32)(u64)mem_align(128,128),(u32)(u64)gcmGetLabelAddress(64));
    signal_spu_ppu();
    signal_spu_rsx();

    P = transpose(Matrix4::perspective(DEGTORAD(45.0f),aspect_ratio,1.0f,3000.0f));

    setRenderTarget(curr_fb);
    rsxFinish(context,0);

    ret = atexit(program_exit_callback);
    ret = sysUtilRegisterCallback(0,sysutil_exit_callback,NULL);

    delete cube;

    running = 1;
    while(running) {
        ret = sysUtilCheckCallback();

        ioPadGetInfo(&padinfo);
        for(i=0; i<MAX_PADS; i++) {
            if(padinfo.status[i]) {
                ioPadGetData(i, &paddata);

                if(paddata.BTN_CROSS) {
                    return 0;
                }
            }

        }

        drawFrame();
        flip();
    }

    return 0;
}
예제 #6
0
//////////////////////////////////////////////////////////////
// Reading in column state sequences for prefiltering
//////////////////////////////////////////////////////////////
  void Prefilter::init_prefilter(FFindexDatabase* cs219_database) {
    // Set up variables for prefiltering
    num_dbs = cs219_database->db_index->n_entries;
    first = (unsigned char**) mem_align(ALIGN_FLOAT, num_dbs * sizeof(unsigned char*));
    length = (int*) mem_align(ALIGN_FLOAT, num_dbs * sizeof(int));
    dbnames = (char**) mem_align(ALIGN_FLOAT, num_dbs * sizeof(char*));
    for (size_t n = 0; n < num_dbs; n++) {
      ffindex_entry_t* entry = ffindex_get_entry_by_index(
          cs219_database->db_index, n);
      first[n] = (unsigned char*) ffindex_get_data_by_entry(
          cs219_database->db_data, entry);
      length[n] = entry->length - 1;
      dbnames[n] = new char[strlen(entry->name) + 1];
      strcpy(dbnames[n], entry->name);
    }

    //check if cs219 format is new binary format
    checkCSFormat(5);

    HH_LOG(INFO) << "Searching " << num_dbs
        << " column state sequences." << std::endl;
  }
예제 #7
0
OSStatus host_platform_bus_init( void )
{
    edma_user_config_t g_edmaUserConfig;

    /* Create a semephore to check for completed eDMA transfers. */
    mico_rtos_init_semaphore(&spi_transfer_finished_semaphore, 1);
    MCU_CLOCKS_NEEDED();
    
    configure_spi_pins(0); // initlize spi0 GPIO
    PORT_HAL_SetMuxMode(PORTD_BASE,0u,kPortMuxAsGpio); // configure CS as gpio, use software configure CS.
    GPIO_DRV_OutputPinInit(&spiCsPin[0]);
    SPI0_CS_DISABLE;
    /* Initialize eDMA & DMAMUX */
    g_edmaUserConfig.chnArbitration = kEDMAChnArbitrationRoundrobin;
    g_edmaUserConfig.notHaltOnError = false;
    EDMA_DRV_Init(&g_edmaState, &g_edmaUserConfig);
    /* DSPI Master Configuration */
    dspi_edma_master_setup(&dspiMasterState, 0, 10000000, 8);
    
    MCU_CLOCKS_NOT_NEEDED();
    dmaSPITX.dmaChanNum = DMA_CH0;
    dmaSPITX.dmaCh = &dmaCh0;
    dmaSPITX.type = kEDMAMemoryToPeripheral;
    dmaSPITX.chSource = kDmaRequestMux0SPI0Tx;
    dmaSPITX.srcAddr = (uint32_t)NULL;
    dmaSPITX.destAddr = (uint32_t)&SPI0->PUSHR;
    dmaSPITX.length = 0;
    dmaSPITX.size = 4;
    dmaSPITX.watermark = 4;
    dmaSPITX.period = 0x01U;
    dmaSPITX.dmaCallBack = stop_edma_loop;
    

    dmaSPIRX.dmaChanNum = DMA_CH1;
    dmaSPIRX.dmaCh = &dmaCh1;
    dmaSPIRX.type = kEDMAPeripheralToMemory;
    dmaSPIRX.chSource = kDmaRequestMux0SPI0Rx;
    dmaSPIRX.srcAddr = (uint32_t)&SPI0->POPR;
    dmaSPIRX.destAddr = (uint32_t)NULL;
    dmaSPIRX.length = 0;
    dmaSPIRX.size = 1;
    dmaSPIRX.watermark = 1;
    dmaSPIRX.period = 0x01U;
    dmaSPIRX.dmaCallBack = stop_edma_loop_putsem;
    dmaSPIRX.dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * dmaSPIRX.period, 32);

    spi_status_print(SPI0);
    return kNoErr;
}
예제 #8
0
s32 SetBootState( u8 type , u8 flags , u8 returnto , u8 discstate )
{
	StateFlags *sf = (StateFlags *)mem_align( 32, sizeof(StateFlags) );
	memset( sf, 0, sizeof(StateFlags) );

	s32 fd = ISFS_Open("/title/00000001/00000002/data/state.dat", 1|2 );
	if(fd < 0)
	{
		mem_free( sf );
		ISFS_Close(fd);
		return -1;
	}
	
	s32 ret = ISFS_Read(fd, sf, sizeof(StateFlags));

	if(ret != sizeof(StateFlags))
	{
		mem_free( sf );
		ISFS_Close(fd);
		return -2 ;
	}

	sf->type = type;
	sf->returnto = returnto;
	sf->flags = flags;
	sf->discstate = discstate;
	sf->checksum= __CalcChecksum((u32*)sf, sizeof(StateFlags));

	if(ISFS_Seek( fd, 0, 0 )<0)
	{
		mem_free( sf );
		ISFS_Close(fd);
		return -3;
	}

	if(ISFS_Write(fd, sf, sizeof(StateFlags))!=sizeof(StateFlags))
	{
		mem_free( sf );
		ISFS_Close(fd);
		return -4;
	}

	ISFS_Close(fd);

	mem_free( sf );
	return 1;

}
예제 #9
0
CACHE* cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t startOfPartition, sec_t endOfPartition, sec_t sectorSize) {
	CACHE* cache;
	unsigned int i;
	CACHE_ENTRY* cacheEntries;

	if(numberOfPages==0 || sectorsPerPage==0) return NULL;

	if (numberOfPages < 32) {
		numberOfPages = 32;
	}

	if (sectorsPerPage < 16) {
		sectorsPerPage = 16;
	}

	cache = (CACHE*) mem_alloc (sizeof(CACHE));
	if (cache == NULL) {
		return NULL;
	}

	cache->disc = discInterface;
	cache->endOfPartition = endOfPartition;
	cache->numberOfPages = numberOfPages;
	cache->sectorsPerPage = sectorsPerPage;
	cache->sectorSize = sectorSize;


	cacheEntries = (CACHE_ENTRY*) mem_alloc ( sizeof(CACHE_ENTRY) * numberOfPages);
	if (cacheEntries == NULL) {
		mem_free (cache);
		return NULL;
	}

	for (i = 0; i < numberOfPages; i++) {
		cacheEntries[i].sector = CACHE_FREE;
		cacheEntries[i].count = 0;
		cacheEntries[i].last_access = 0;
		cacheEntries[i].dirty = false;
		cacheEntries[i].cache = (uint8_t*) mem_align (32, sectorsPerPage * cache->sectorSize);
	}

	cache->cacheEntries = cacheEntries;

	return cache;
}
예제 #10
0
파일: gleam_mem.c 프로젝트: andrakis/gleam
void mem_allocate(gnum location, mem_node_t *dest) {
	mem_node_t *new_node = (mem_node_t*)malloc(sizeof(mem_node_t));

	new_node->start = mem_align(location);
	new_node->range = PAGE_SIZE;
	new_node->page = (char*)malloc(PAGE_SIZE);
	memset(new_node->page, 0, PAGE_SIZE);

	if (location < dest->start) {
		new_node->next = dest;
		new_node->prev = dest->prev;
		dest->prev = new_node;
	} else {
		new_node->next = dest->next;
		new_node->prev = dest;
		dest->next = new_node;
	}
}
예제 #11
0
s32 CheckBootState( void )
{
	StateFlags *sf = (StateFlags *)mem_align( 32, sizeof(StateFlags) );
	memset( sf, 0, sizeof(StateFlags) );
	s32 fd = ISFS_Open("/title/00000001/00000002/data/state.dat", 1);
	if(fd < 0)
	{
		mem_free(sf);
		return 0;
	}
	s32 ret = ISFS_Read(fd, sf, sizeof(StateFlags));
	ISFS_Close(fd);
	if(ret != sizeof(StateFlags))
	{
		mem_free(sf);
		return 0;
	}
	u8 r = sf->type;
	mem_free( sf );
	return r;
}
예제 #12
0
StateFlags GetStateFlags( void )
{
	StateFlags *sf = (StateFlags *)mem_align( 32, sizeof(StateFlags) );
	StateFlags State;
	memset( sf, 0, sizeof(StateFlags) );
	s32 fd = ISFS_Open("/title/00000001/00000002/data/state.dat", 1);
	if(fd < 0)
	{
		mem_free(sf);
		return State;
	}
	s32 ret = ISFS_Read(fd, sf, sizeof(StateFlags));
	ISFS_Close(fd);
	if(ret != sizeof(StateFlags))
	{
		mem_free(sf);
		return State;
	}
	memcpy((StateFlags*)&State,sf,sizeof(StateFlags));
	mem_free( sf );
	return State;
}
예제 #13
0
파일: info.c 프로젝트: zrho/Oxygen
uintptr_t boot_modules_relocate(boot_info_t *info, uintptr_t placement)
{
    // Align placement
    placement = mem_align(placement, 0x1000);

    // Sort modules by begin address (ASC)
    boot_info_mod_t *sorted = 0;
    boot_info_mod_t *sorted_end = sorted;
    
    while (0 != info->mods) {
        // Find ealiest module
        boot_info_mod_t *current = (boot_info_mod_t *) (uintptr_t) info->mods;
        boot_info_mod_t *prev = 0;
        boot_info_mod_t *min_prev = 0;
        boot_info_mod_t *min = 0;
        
        while (0 != current) {
            if (0 == min || current->address < min->address) {
                min = current;
                min_prev = prev;
            }
            
            // Next
            prev = current;
            current = (boot_info_mod_t *) (uintptr_t) current->next;
        }
        
        // Remove from list
        if (0 == min_prev)
            info->mods = min->next;
        else
            min_prev->next = min->next;
            
        // Add to sorted list        
        if (0 == sorted_end)
            sorted = sorted_end = min;
        else {
            sorted_end->next = (uintptr_t) min;
            sorted_end = min;
        }
    }
    
    // Replace lists
    info->mods = (uintptr_t) sorted;
    
    // Move modules
    boot_info_mod_t *current = (boot_info_mod_t *) (uintptr_t) info->mods;
    
    while (0 != current) {
        memcpy(
            (void *) placement,
            (void *) ((uintptr_t) current->address),
            (size_t) current->length);
        
        current->address = (uint64_t) placement;
        placement += (uintptr_t) current->length;
        placement = mem_align(placement, 0x1000);
        current = (boot_info_mod_t *) (uintptr_t) current->next;
    }
    
    return placement;
}
예제 #14
0
s8 GetTitleName(u64 id, u32 app, char* name,u8* _dst_uncode_name) {
	s32 r;
    int lang = 1; //CONF_GetLanguage();
    /*
    languages:
    enum {
	CONF_LANG_JAPANESE = 0,
	CONF_LANG_ENGLISH,
	CONF_LANG_GERMAN,
	CONF_LANG_FRENCH,
	CONF_LANG_SPANISH,
	CONF_LANG_ITALIAN,
	CONF_LANG_DUTCH,
	CONF_LANG_SIMP_CHINESE,
	CONF_LANG_TRAD_CHINESE,
	CONF_LANG_KOREAN
	};
	cause we dont support unicode stuff in font.cpp we will force to use english then(1)
    */
	u8 return_unicode_name = 0;
	if(_dst_uncode_name == NULL)
	{
		return_unicode_name = 0;
	}
	else
	{
		return_unicode_name = 1;
	}
    char file[256] ATTRIBUTE_ALIGN(32);
	memset(file,0,256);
    sprintf(file, "/title/%08x/%08x/content/%08x.app", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF), app);
	gdprintf("GetTitleName : %s\n",file);
	u32 cnt ATTRIBUTE_ALIGN(32);
	cnt = 0;
	IMET *data = (IMET *)mem_align(32, ALIGN32( sizeof(IMET) ) );
	if(data == NULL)
	{
		gprintf("GetTitleName : IMET header align failure\n");
		return -1;
	}
	memset(data,0,sizeof(IMET) );
	r = ES_GetNumTicketViews(id, &cnt);
	if(r < 0)
	{
		gprintf("GetTitleName : GetNumTicketViews error %d!\n",r);
		mem_free(data);
		return -1;
	}
	tikview *views = (tikview *)mem_align( 32, sizeof(tikview)*cnt );
	if(views == NULL)
	{
		mem_free(data);
		return -2;
	}
	r = ES_GetTicketViews(id, views, cnt);
	if (r < 0)
	{
		gprintf("GetTitleName : GetTicketViews error %d \n",r);
		mem_free(data);
		mem_free(views);
		return -3;
	}

	//lets get this party started with the right way to call ES_OpenTitleContent. and not like how libogc < 1.8.3 does it. patch was passed on , and is done correctly in 1.8.3
	//the right way is ES_OpenTitleContent(u64 TitleID,tikview* views,u16 Index); note the views >_>
	s32 fh = ES_OpenTitleContent(id, views, 0);
	if (fh == -106)
	{
		CheckTitleOnSD(id);
		mem_free(data);
		mem_free(views);
		return -106;
	}
	else if(fh < 0)
	{
		//ES method failed. remove tikviews from memory and fall back on ISFS method
		gprintf("GetTitleName : ES_OpenTitleContent error %d\n",fh);
		mem_free(views);
		fh = ISFS_Open(file, ISFS_OPEN_READ);
		// f**k failed. lets check SD & GTFO
		if (fh == -106)
		{
			CheckTitleOnSD(id);
			return -106;
		}
		else if (fh < 0)
		{
			mem_free(data);
			gprintf("open %s error %d\n",file,fh);
			return -5;
		}
		// read the completed IMET header
		r = ISFS_Read(fh, data, sizeof(IMET));
		if (r < 0) {
			gprintf("IMET read error %d\n",r);
			ISFS_Close(fh);
			mem_free(data);
			return -6;
		}
		ISFS_Close(fh);
	}
	else
	{
		//ES method
		r = ES_ReadContent(fh,(u8*)data,sizeof(IMET));
		if (r < 0) {
			gprintf("GetTitleName : ES_ReadContent error %d\n",r);
			ES_CloseContent(fh);
			mem_free(data);
			mem_free(views);
			return -8;
		}
		//free data and let it point to IMET_data so everything else can work just fine
		ES_CloseContent(fh);
		mem_free(views);
	}
	char str[10][84];
	char str_unprocessed[10][84];
	//clear any memory that is in the place of the array cause we dont want any confusion here
	memset(str,0,10*84);
	if(return_unicode_name)
		memset(str_unprocessed,0,10*84);
	if(data->imet == 0x494d4554) // check if its a valid imet header
	{
		for(u8 y =0;y <= 9;y++)
		{
			u8 p = 0;
			u8 up = 0;
			for(u8 j=0;j<83;j++)
			{
				if(data->names[y][j] < 0x20)
					if(return_unicode_name && data->names[y][j] == 0x00)
						str_unprocessed[y][up++] = data->names[y][j];
					else
						continue;
				else if(data->names[y][j] > 0x7E)
					continue;
				else
				{
					str[y][p++] = data->names[y][j];
					str_unprocessed[y][up++] = data->names[y][j];
				}
			}
			str[y][83] = '\0';

		}
		mem_free(data);
	}
	else
	{
		gprintf("invalid IMET header for 0x%08x/0x%08x\n", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF));
		return -9;
	}
	if(str[lang][0] != '\0')
	{
		gdprintf("GetTitleName : title %s\n",str[lang]);
		snprintf(name,255, "%s", str[lang]);
		if (return_unicode_name && str_unprocessed[lang][1] != '\0')
		{
			memcpy(_dst_uncode_name,&str_unprocessed[lang][0],83);
		}
		else if(return_unicode_name)
			gprintf("WARNING : empty unprocessed string\n");
	}
	else
		gprintf("GetTitleName: no name found\n");
	memset(str,0,10*84);
	memset(str_unprocessed,0,10*84);
	return 1;
}
예제 #15
0
s8 LoadHacks_Hash( bool Force_Load_Nand )
{	
	if( hacks_hash.size() ) //hacks_hash already loaded
	{
		hacks_hash.clear();
		if(states_hash)
		{
			mem_free(states_hash);
		}
	}
	if(foff != 0)
		foff=0;
	bool mode = true;
	s32 fd=0;
	char *buf=NULL;
	STACK_ALIGN(fstats,status,sizeof(fstats),32);
	unsigned int size=0;
	FILE* in = NULL;
	if(!Force_Load_Nand)
	{
		in = fopen ("fat:/apps/priiloader/hacks_hash.ini","rb");
		if(!in)
			gprintf("fopen error : strerror %s\n",strerror(errno));

	}
	if( !in )
	{
		fd = ISFS_Open("/title/00000001/00000002/data/hackshas.ini", 1 );
		if( fd < 0 )
		{
			gprintf("LoadHacks : hacks_hash.ini not on FAT or Nand. ISFS_Open error %d\n",fd);
			return 0;
		} 
		mode = false;
	}
	if( mode )	//read file from FAT
	{
		//read whole file in
		fseek( in, 0, SEEK_END );
		size = ftell(in);
		fseek( in, 0, 0);

		if( size == 0 )
		{
			PrintFormat( 1, ((640/2)-((strlen("Error \"hacks_hash.ini\" is 0 byte!"))*13/2))>>1, 208, "Error \"hacks_hash.ini\" is 0 byte!");
			sleep(5);
			return 0;
		}

		buf = (char*)mem_align( 32, ALIGN32(size));
		if( buf == NULL )
		{
			error = ERROR_MALLOC;
			return 0;
		}
		memset( buf, 0, size );
		if(fread( buf, sizeof( char ), size, in ) != size )
		{
			mem_free(buf);
			PrintFormat( 1, ((640/2)-((strlen("Error reading \"hacks_hash.ini\""))*13/2))>>1, 208, "Error reading \"hacks_hash.ini\"");
			sleep(5);
			return 0;
		}