@@ -87,13 +87,14 @@ const char* GYMPlayer::GetPlayerName(void) const
8787
8888/* static*/ UINT8 GYMPlayer::PlayerCanLoadFile (DATA_LOADER *dataLoader)
8989{
90- DataLoader_ReadUntil (dataLoader,0x04 );
90+ DataLoader_ReadUntil (dataLoader, 0x04 );
9191 if (DataLoader_GetSize (dataLoader) < 0x04 )
9292 return 0xF1 ; // file too small
9393 if (! memcmp (&DataLoader_GetData (dataLoader)[0x00 ], " GYMX" , 4 ))
9494 return 0x00 ; // valid GYMX header
95- if (DataLoader_GetData (dataLoader)[0x00 ] <= 0x03 ) // check for a valid command byte
96- return 0x00 ; // TODO: Check the first 0x40 bytes for a better heuristic
95+ DataLoader_ReadUntil (dataLoader, 0x200 );
96+ if (CheckRawGYMFile (DataLoader_GetSize (dataLoader), DataLoader_GetData (dataLoader)))
97+ return 0x00 ; // the heuristic for detection raw GYM files found no issues
9798 return 0xF0 ; // invalid file
9899}
99100
@@ -102,6 +103,61 @@ UINT8 GYMPlayer::CanLoadFile(DATA_LOADER *dataLoader) const
102103 return this ->PlayerCanLoadFile (dataLoader);
103104}
104105
106+ /* static*/ bool GYMPlayer::CheckRawGYMFile (UINT32 dataLen, const UINT8* data)
107+ {
108+ UINT32 filePos;
109+ bool fileEnd;
110+ UINT8 curCmd;
111+ UINT8 curReg;
112+
113+ fileEnd = false ;
114+ filePos = 0x00 ;
115+
116+ while (filePos < dataLen && data[filePos] == 0x00 )
117+ filePos ++;
118+ if (filePos >= dataLen)
119+ return false ; // only 00s - assume invalid file
120+
121+ while (! fileEnd && filePos < dataLen)
122+ {
123+ curCmd = data[filePos];
124+ filePos ++;
125+ switch (curCmd)
126+ {
127+ case 0x00 : // wait 1 frame
128+ break ;
129+ case 0x01 : // YM2612 port 0
130+ case 0x02 : // YM2612 port 1
131+ if (filePos + 0x02 > dataLen)
132+ break ;
133+ curReg = data[filePos + 0x00 ];
134+ // valid YM2612 registers are:
135+ // port 0: 21..BF
136+ // port 1: 30..BF
137+ if (curReg >= 0xC0 )
138+ return false ;
139+ if (curCmd == 0x01 && curReg < 0x21 )
140+ return false ;
141+ if (curCmd == 0x02 && curReg < 0x30 )
142+ return false ;
143+ filePos += 0x02 ;
144+ break ;
145+ case 0x03 : // SEGA PSG
146+ if (filePos + 0x01 > dataLen)
147+ break ;
148+ curReg = data[filePos];
149+ if (curReg >= 0x40 && curReg < 0x80 )
150+ return false ; // invalid PSG values
151+ filePos += 0x01 ;
152+ break ;
153+ default :
154+ return false ; // assume invalid file
155+ }
156+ }
157+
158+ return true ;
159+ }
160+
105161UINT8 GYMPlayer::LoadFile (DATA_LOADER *dataLoader)
106162{
107163 _dLoad = NULL ;
0 commit comments