// // /home/ms/source/sidplay/libsidplay/fformat/RCS/sid_.cpp,v // #include "sid_.h" const char text_format[] = "Raw plus SIDPLAY ASCII text file (SID)"; const char text_truncatedError[] = "ERROR: SID file is truncated"; const char text_noMemError[] = "ERROR: Not enough free memory"; const char keyword_id[] = "SIDPLAY INFOFILE"; const char keyword_name[] = "NAME="; // No white-space characters const char keyword_author[] = "AUTHOR="; // in these keywords, because const char keyword_copyright[] = "COPYRIGHT="; // we want to use a white-space const char keyword_address[] = "ADDRESS="; // eating string stream to const char keyword_songs[] = "SONGS="; // parse most of the header. const char keyword_speed[] = "SPEED="; const char keyword_musPlayer[] = "SIDSONG=YES"; const uint sidMinFileSize = 1+sizeof(keyword_id); // Just to avoid a first segm.fault. const uint parseChunkLen = 80; // Enough for all keywords incl. their values. bool sidTune::SID_fileSupport(const void* dataBuffer, udword dataBufLen, const void* sidBuffer, udword sidBufLen) { // Remove any format description or error string. info.formatString = 0; // Make sure SID buffer pointer is not zero. // Check for a minimum file size. If it is smaller, we will not proceed. if ((sidBuffer==0) || (sidBufLen> c; pParseChunk[i] = c; } pParseChunk[parseChunkLen]=0; // Now check for the possible keywords. // ADDRESS if ( myStrNcaseCmp( pParseChunk, keyword_address ) == 0 ) { skipToEqu( parseStream ); info.loadAddr = (uword)readHex( parseStream ); if ( !parseStream ) break; info.initAddr = (uword)readHex( parseStream ); if ( !parseStream ) break; info.playAddr = (uword)readHex( parseStream ); hasAddress = true; } // NAME else if ( myStrNcaseCmp( pParseChunk, keyword_name ) == 0 ) { copyStringValueToEOL( pParseBuf, &infoString[0][0], infoStringLen ); info.nameString = &infoString[0][0]; info.infoString[0] = &infoString[0][0]; hasName = true; } // AUTHOR else if ( myStrNcaseCmp( pParseChunk, keyword_author ) == 0 ) { copyStringValueToEOL( pParseBuf, &infoString[1][0], infoStringLen ); info.authorString = &infoString[1][0]; info.infoString[1] = &infoString[1][0]; hasAuthor = true; } // COPYRIGHT else if ( myStrNcaseCmp( pParseChunk, keyword_copyright ) == 0 ) { copyStringValueToEOL( pParseBuf, &infoString[2][0], infoStringLen ); info.copyrightString = &infoString[2][0]; info.infoString[2] = &infoString[2][0]; hasCopyright = true; } // SONGS else if ( myStrNcaseCmp( pParseChunk, keyword_songs ) == 0 ) { skipToEqu( parseStream ); info.songs = (uword)readDec( parseStream ); info.startSong = (uword)readDec( parseStream ); hasSongs = true; } // SPEED else if ( myStrNcaseCmp( pParseChunk, keyword_speed ) == 0 ) { skipToEqu( parseStream ); oldStyleSpeed = readHex(parseStream); hasSpeed = true; } // SIDSONG else if ( myStrNcaseCmp( pParseChunk, keyword_musPlayer ) == 0 ) { info.musPlayer = true; } }; delete[] pParseChunk; // Again check for the ``required'' values. if ( hasAddress || hasName || hasAuthor || hasCopyright || hasSongs || hasSpeed ) { // Create the speed/clock setting table. convertOldStyleSpeedToTables(oldStyleSpeed); // loadAddr = 0 means, the address is stored in front of the C64 data. // We cannot verify whether the dataBuffer contains valid data. // All we want to know is whether the SID buffer is valid. // If data is present, we access it (here to get the C64 load address). if (info.loadAddr==0 && (dataBufLen>=(fileOffset+2)) && dataBuffer!=0) { const ubyte* pDataBufCp = (const ubyte*)dataBuffer + fileOffset; info.loadAddr = readEndian( *(pDataBufCp + 1), *pDataBufCp ); fileOffset += 2; // begin of data } // Keep compatibility to PSID/SID. if ( info.initAddr == 0 ) { info.initAddr = info.loadAddr; } info.numberOfInfoStrings = 3; // We finally accept the input data. info.formatString = text_format; return true; } else { // Something is missing (or damaged ?). // Error string set above. return false; } } } bool sidTune::SID_fileSupportSave( ofstream& fMyOut ) { fMyOut << keyword_id << endl << keyword_address << hex << setw(4) << setfill('0') << 0 << ',' << hex << setw(4) << info.initAddr << "," << hex << setw(4) << info.playAddr << endl << keyword_songs << dec << (int)info.songs << "," << (int)info.startSong << endl; udword oldStyleSpeed = 0; int maxBugSongs = ((info.songs <= 32) ? info.songs : 32); for (int s = 0; s < maxBugSongs; s++) { if (songSpeed[s] == SIDTUNE_SPEED_CIA_1A) { oldStyleSpeed |= (1<