示例#1
0
文件: main.c 项目: weese/tinysid
bool IsPSIDFile(const char *file)
{
    // Load header
    uint8_t header[PSID_MAX_HEADER_LENGTH];
    if (!LoadPSIDHeader(file, header))
        return false;

    // Check header
    return IsPSIDHeader(header);
}
示例#2
0
int SidFile::Parse(string file)
{
	FILE *f = fopen(file.c_str(), "rb");
	
	if(f == NULL)
	{
		return SIDFILE_ERROR_FILENOTFOUND;
	}
	
	uint8_t header[PSID_MAX_HEADER_LENGTH];
	memset(header, 0, PSID_MAX_HEADER_LENGTH);
	
	size_t read = fread(header, 1, PSID_MAX_HEADER_LENGTH, f);
	
	if(read < PSID_MIN_HEADER_LENGTH || !IsPSIDHeader(header))
	{
		fclose(f);
		return SIDFILE_ERROR_MALFORMED;
	}

	numOfSongs = Read16(header, SIDFILE_PSID_NUMBER);
	
	if(numOfSongs == 0)
	{
		numOfSongs = 1;
	}
	
	firstSong = Read16(header, SIDFILE_PSID_DEFSONG);
	if(firstSong)
	{
		firstSong--;
	}
	if (firstSong >= numOfSongs)
	{
		firstSong = 0;
	}

	initAddr = Read16(header, SIDFILE_PSID_INIT);
	playAddr = Read16(header, SIDFILE_PSID_MAIN);
	speedFlags = Read32(header, SIDFILE_PSID_SPEED);

	moduleName = (char *)(header + SIDFILE_PSID_NAME);
	
	authorName = (char *)(header + SIDFILE_PSID_AUTHOR);
	
	string copyrightInfo = (char *)(header + SIDFILE_PSID_COPYRIGHT);

	// Seek to start of module data
	fseek(f, Read16(header, SIDFILE_PSID_LENGTH), SEEK_SET);

	// Find load address
	loadAddr = Read16(header, SIDFILE_PSID_START);
	if(loadAddr == 0)
	{
		uint8_t lo = fgetc(f);
		uint8_t hi = fgetc(f);
		loadAddr = (hi << 8) | lo;
	}
	
	if(initAddr == 0)
	{
		initAddr = loadAddr;
	}

	// Load module data
	dataLength = fread(dataBuffer, 1, 0x10000, f);
	
	fclose(f);

	return SIDFILE_OK;
}
示例#3
0
文件: main.c 项目: weese/tinysid
bool LoadPSIDFile(const char *file)
{
    // Open file
    FILE *f = fopen(file, "rb");
    if (f == NULL)
        return false;

    // Clear C64 RAM
    MemoryClear();
    psid_loaded = false;

    // Load and check header
    uint8_t header[PSID_MAX_HEADER_LENGTH];
    memset(header, 0, PSID_MAX_HEADER_LENGTH);
    size_t actual = fread(header, 1, PSID_MAX_HEADER_LENGTH, f);
    if (actual < PSID_MIN_HEADER_LENGTH || !IsPSIDHeader(header)) {
        fclose(f);
        return false;
    }

    // Extract data from header
    number_of_songs = read_psid_16(header, PSID_NUMBER);
    if (number_of_songs == 0)
        number_of_songs = 1;
    current_song = read_psid_16(header, PSID_DEFSONG);
    if (current_song)
        current_song--;
    if (current_song >= number_of_songs)
        current_song = 0;

    init_adr = read_psid_16(header, PSID_INIT);
    play_adr = read_psid_16(header, PSID_MAIN);
    play_adr_from_irq_vec = (play_adr == 0);

    speed_flags = read_psid_32(header, PSID_SPEED);

    strncpy(module_name, (char *)(header + PSID_NAME), 32);
    strncpy(author_name, (char *)(header + PSID_AUTHOR), 32);
    strncpy(copyright_info, (char *)(header + PSID_COPYRIGHT), 32);
    module_name[32] = 0;
    author_name[32] = 0;
    copyright_info[32] = 0;

    // Seek to start of module data
    fseek(f, read_psid_16(header, PSID_LENGTH), SEEK_SET);

    // Find load address
    uint16_t load_adr = read_psid_16(header, PSID_START);
    if (load_adr == 0) {    // Load address is at start of module data
        uint8_t lo = fgetc(f);
        uint8_t hi = fgetc(f);
        load_adr = (hi << 8) | lo;
    }
    if (init_adr == 0)        // Init routine address is equal to load address
        init_adr = load_adr;

    // Load module data to C64 RAM
    fread(ram + load_adr, 1, RAM_SIZE - load_adr, f);
    fclose(f);

    // Select default song
    SelectSong(current_song);

    // Everything OK
    psid_loaded = true;
    return true;
}