static MDFN_COLD bool DetectSGXCD(std::vector<CDIF*>* CDInterfaces) { CDIF *cdiface = (*CDInterfaces)[0]; CDUtility::TOC toc; uint8 sector_buffer[2048]; bool ret = false; memset(sector_buffer, 0, sizeof(sector_buffer)); cdiface->ReadTOC(&toc); // Check all data tracks for the 16-byte magic(4D 65 64 6E 61 66 65 6E 74 AB 90 19 42 62 7D E6) at offset 0x86A(assuming mode 1 sectors). for(int32 track = toc.first_track; track <= toc.last_track; track++) { if(toc.tracks[track].control & 0x4) { if(cdiface->ReadSector(sector_buffer, toc.tracks[track].lba + 1, 1) != 0x1) continue; if(MDFN_de64msb(§or_buffer[0x6A]) == 0x4D65646E6166656EULL && MDFN_de64msb(§or_buffer[0x6A + 8]) == 0x74AB901942627DE6ULL) ret = true; } } return ret; }
static MDFN_COLD bool TestMagicCD(std::vector<CDIF *> *CDInterfaces) { static const uint8 magic_test[0x20] = { 0x82, 0xB1, 0x82, 0xCC, 0x83, 0x76, 0x83, 0x8D, 0x83, 0x4F, 0x83, 0x89, 0x83, 0x80, 0x82, 0xCC, 0x92, 0x98, 0x8D, 0xEC, 0x8C, 0xA0, 0x82, 0xCD, 0x8A, 0x94, 0x8E, 0xAE, 0x89, 0xEF, 0x8E, 0xD0 }; uint8 sector_buffer[2048]; CDIF *cdiface = (*CDInterfaces)[0]; CDUtility::TOC toc; bool ret = false; memset(sector_buffer, 0, sizeof(sector_buffer)); cdiface->ReadTOC(&toc); for(int32 track = toc.first_track; track <= toc.last_track; track++) { if(toc.tracks[track].control & 0x4) { if(cdiface->ReadSector(sector_buffer, toc.tracks[track].lba, 1) != 0x1) break; if(!memcmp((char*)sector_buffer, (char *)magic_test, 0x20)) ret = true; // PCE CD BIOS apparently only looks at the first data track. break; } } // If it's a PC-FX CD(Battle Heat), return false. // This is very kludgy. for(int32 track = toc.first_track; track <= toc.last_track; track++) { if(toc.tracks[track].control & 0x4) { if(cdiface->ReadSector(sector_buffer, toc.tracks[track].lba, 1) == 0x1) { if(!strncmp("PC-FX:Hu_CD-ROM", (char*)sector_buffer, strlen("PC-FX:Hu_CD-ROM"))) { return false; } } } } // Now, test for the Games Express CD games. The GE BIOS seems to always look at sector 0x10, but only if the first track is a // data track. if(toc.first_track == 1 && (toc.tracks[1].control & 0x4)) { if(cdiface->ReadSector(sector_buffer, 0x10, 1) == 0x1) { if(!memcmp((char *)sector_buffer + 0x8, "HACKER CD ROM SYSTEM", 0x14)) { ret = true; } } } return(ret); }
uint64 CDIF_Stream_Thing::read(void *data, uint64 count, bool error_on_eos) { if(count > (((uint64)sector_count * 2048) - position)) { if(error_on_eos) { throw MDFN_Error(0, "EOF"); } count = ((uint64)sector_count * 2048) - position; } if(!count) return(0); for(uint64 rp = position; rp < (position + count); rp = (rp &~ 2047) + 2048) { uint8 buf[2048]; if(!cdintf->ReadSector(buf, start_lba + (rp / 2048), 1)) { throw MDFN_Error(ErrnoHolder(EIO)); } //::printf("Meow: %08llx -- %08llx\n", count, (rp - position) + std::min<uint64>(2048 - (rp & 2047), count - (rp - position))); memcpy((uint8*)data + (rp - position), buf + (rp & 2047), std::min<uint64>(2048 - (rp & 2047), count - (rp - position))); } position += count; return count; }
uint64 CDIF_Stream_Thing::read(void *data, uint64 count, bool error_on_eos) { if(count > (((uint64)sector_count * 2048) - position)) count = ((uint64)sector_count * 2048) - position; if(!count) return(0); for(uint64 rp = position; rp < (position + count); rp = (rp &~ 2047) + 2048) { uint8 buf[2048]; cdintf->ReadSector(buf, start_lba + (rp / 2048), 1); memcpy((uint8*)data + (rp - position), buf + (rp & 2047), std::min<uint64>(2048 - (rp & 2047), count - (rp - position))); } position += count; return count; }