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); }
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; }
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; }