diff --git a/source/Disk.cpp b/source/Disk.cpp index f5330293..8bfab4ff 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -262,10 +262,11 @@ bool Disk2InterfaceCard::IsDriveValid(const int drive) //=========================================================================== -void Disk2InterfaceCard::AllocTrack(const int drive) +void Disk2InterfaceCard::AllocTrack(const int drive, const UINT minSize/*=NIBBLES_PER_TRACK*/) { FloppyDisk* pFloppy = &m_floppyDrive[drive].m_disk; - pFloppy->m_trackimage = (LPBYTE)VirtualAlloc(NULL, NIBBLES_PER_TRACK, MEM_COMMIT, PAGE_READWRITE); + const UINT maxNibblesPerTrack = ImageGetMaxNibblesPerTrack(m_floppyDrive[drive].m_disk.m_imagehandle); + pFloppy->m_trackimage = new BYTE[ MAX(minSize,maxNibblesPerTrack) ]; } //=========================================================================== @@ -345,7 +346,7 @@ void Disk2InterfaceCard::EjectDiskInternal(const int drive) if (pFloppy->m_trackimage) { - VirtualFree(pFloppy->m_trackimage, 0, MEM_RELEASE); + delete [] pFloppy->m_trackimage; pFloppy->m_trackimage = NULL; pFloppy->m_trackimagedata = false; } @@ -1843,7 +1844,7 @@ void Disk2InterfaceCard::SaveSnapshotFloppy(YamlSaveHelper& yamlSaveHelper, UINT if (m_floppyDrive[unit].m_disk.m_trackimage) { YamlSaveHelper::Label image(yamlSaveHelper, "%s:\n", SS_YAML_KEY_TRACK_IMAGE); - yamlSaveHelper.SaveMemory(m_floppyDrive[unit].m_disk.m_trackimage, NIBBLES_PER_TRACK); + yamlSaveHelper.SaveMemory(m_floppyDrive[unit].m_disk.m_trackimage, ImageGetMaxNibblesPerTrack(m_floppyDrive[unit].m_disk.m_imagehandle)); } } @@ -1905,7 +1906,7 @@ bool Disk2InterfaceCard::LoadSnapshotFloppy(YamlLoadHelper& yamlLoadHelper, UINT if (InsertDisk(unit, filename.c_str(), dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE) bImageError = true; - // DiskInsert() zeros m_floppyDrive[unit], then sets up: + // InsertDisk() zeros m_floppyDrive[unit], then sets up: // . m_imagename // . m_fullname // . m_bWriteProtected @@ -1933,7 +1934,10 @@ bool Disk2InterfaceCard::LoadSnapshotFloppy(YamlLoadHelper& yamlLoadHelper, UINT if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE)) { - yamlLoadHelper.LoadMemory(&track[0], NIBBLES_PER_TRACK); + const UINT maxNibblesPerTrack = ImageGetMaxNibblesPerTrack(m_floppyDrive[unit].m_disk.m_imagehandle); + track.reserve(maxNibblesPerTrack); // expand (but don't shrink) vector's capacity (NB. vector's size doesn't change) + UINT bytes = yamlLoadHelper.LoadMemory(&track[0], maxNibblesPerTrack); + track.resize(bytes); // resize so that vector contains /bytes/ elements yamlLoadHelper.PopMap(); } @@ -1993,7 +1997,7 @@ bool Disk2InterfaceCard::LoadSnapshotDriveUnitv4(YamlLoadHelper& yamlLoadHelper, void Disk2InterfaceCard::LoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit, UINT version) { bool bImageError = false; - std::vector track(NIBBLES_PER_TRACK); + std::vector track(NIBBLES_PER_TRACK); // Default size - may expand vector after loading disk image (eg. WOZ Info.largestTrack) if (version <= 3) bImageError = LoadSnapshotDriveUnitv3(yamlLoadHelper, unit, version, track); @@ -2004,12 +2008,12 @@ void Disk2InterfaceCard::LoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, U if (!bImageError) { if ((m_floppyDrive[unit].m_disk.m_trackimage == NULL) && m_floppyDrive[unit].m_disk.m_nibbles) - AllocTrack(unit); + AllocTrack(unit, track.size()); if (m_floppyDrive[unit].m_disk.m_trackimage == NULL) bImageError = true; else - memcpy(m_floppyDrive[unit].m_disk.m_trackimage, &track[0], NIBBLES_PER_TRACK); + memcpy(m_floppyDrive[unit].m_disk.m_trackimage, &track[0], track.size()); } if (bImageError) diff --git a/source/Disk.h b/source/Disk.h index 85183605..48ffa40e 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -180,7 +180,7 @@ private: Disk_Status_e GetDriveLightStatus(const int drive); bool IsDriveValid(const int drive); void EjectDiskInternal(const int drive); - void AllocTrack(const int drive); + void AllocTrack(const int drive, const UINT minSize=NIBBLES_PER_TRACK); void ReadTrack(const int drive, ULONG uExecutedCycles); void WriteTrack(const int drive); const std::string & DiskGetFullPathName(const int drive); diff --git a/source/DiskImage.cpp b/source/DiskImage.cpp index bf366c8b..889819d0 100644 --- a/source/DiskImage.cpp +++ b/source/DiskImage.cpp @@ -168,8 +168,9 @@ void ImageReadTrack( ImageInfo* const pImageInfo, } else { - for (*pNibbles = 0; *pNibbles < NIBBLES_PER_TRACK; (*pNibbles)++) - pTrackImageBuffer[*pNibbles] = (BYTE)(rand() & 0xFF); + *pNibbles = (int) ImageGetMaxNibblesPerTrack(pImageInfo); + for (int i = 0; i < *pNibbles; i++) + pTrackImageBuffer[i] = (BYTE)(rand() & 0xFF); } } @@ -274,6 +275,11 @@ UINT ImagePhaseToTrack(ImageInfo* const pImageInfo, const float phase, const boo return track; } +UINT ImageGetMaxNibblesPerTrack(ImageInfo* const pImageInfo) +{ + return pImageInfo ? pImageInfo->maxNibblesPerTrack : NIBBLES_PER_TRACK; +} + void GetImageTitle(LPCTSTR pPathname, std::string & pImageName, std::string & pFullName) { TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ]; diff --git a/source/DiskImage.h b/source/DiskImage.h index a9ba6764..9374d4a5 100644 --- a/source/DiskImage.h +++ b/source/DiskImage.h @@ -84,5 +84,6 @@ UINT ImageGetImageSize(ImageInfo* const pImageInfo); bool ImageIsWOZ(ImageInfo* const pImageInfo); BYTE ImageGetOptimalBitTiming(ImageInfo* const pImageInfo); UINT ImagePhaseToTrack(ImageInfo* const pImageInfo, const float phase, const bool limit=true); +UINT ImageGetMaxNibblesPerTrack(ImageInfo* const pImageInfo); void GetImageTitle(LPCTSTR pPathname, std::string & pImageName, std::string & pFullName); diff --git a/source/DiskImageHelper.cpp b/source/DiskImageHelper.cpp index bffe9cb7..1b3194db 100644 --- a/source/DiskImageHelper.cpp +++ b/source/DiskImageHelper.cpp @@ -1181,11 +1181,12 @@ public: *pBitCount = pTRK->bitCount; *pNibbles = (pTRK->bitCount+7) / 8; - _ASSERT(*pNibbles <= NIBBLES_PER_TRACK_WOZ2); - if (*pNibbles > NIBBLES_PER_TRACK_WOZ2) + const UINT maxNibblesPerTrack = pImageInfo->maxNibblesPerTrack; + _ASSERT(*pNibbles <= (int)maxNibblesPerTrack); + if (*pNibbles > (int)maxNibblesPerTrack) return ReadEmptyTrack(pTrackImageBuffer, pNibbles, pBitCount); // TODO: Enlarge track buffer, but for now just return an empty track - memcpy(pTrackImageBuffer, &pImageInfo->pImageBuffer[pTRK->startBlock*512], *pNibbles); + memcpy(pTrackImageBuffer, &pImageInfo->pImageBuffer[pTRK->startBlock*CWOZHelper::BLOCK_SIZE], *pNibbles); } virtual void Write(ImageInfo* pImageInfo, const float phase, LPBYTE pTrackImageBuffer, int nNibbles) @@ -1413,7 +1414,7 @@ ImageError_e CImageHelperBase::CheckGZipFile(LPCTSTR pszImageFilename, ImageInfo DWORD dwSize = nLen; DWORD dwOffset = 0; - CImageBase* pImageType = Detect(pImageInfo->pImageBuffer, dwSize, szExt, dwOffset, pImageInfo->bWriteProtected, pImageInfo->pTrackMap, pImageInfo->optimalBitTiming); + CImageBase* pImageType = Detect(pImageInfo->pImageBuffer, dwSize, szExt, dwOffset, pImageInfo->bWriteProtected, pImageInfo->pTrackMap, pImageInfo->optimalBitTiming, pImageInfo->maxNibblesPerTrack); if (!pImageType) return eIMAGE_ERROR_UNSUPPORTED; @@ -1504,7 +1505,7 @@ ImageError_e CImageHelperBase::CheckZipFile(LPCTSTR pszImageFilename, ImageInfo* DWORD dwSize = nLen; DWORD dwOffset = 0; - CImageBase* pImageType = Detect(pImageInfo->pImageBuffer, dwSize, szExt, dwOffset, pImageInfo->bWriteProtected, pImageInfo->pTrackMap, pImageInfo->optimalBitTiming); + CImageBase* pImageType = Detect(pImageInfo->pImageBuffer, dwSize, szExt, dwOffset, pImageInfo->bWriteProtected, pImageInfo->pTrackMap, pImageInfo->optimalBitTiming, pImageInfo->maxNibblesPerTrack); if (!pImageType) { @@ -1601,7 +1602,7 @@ ImageError_e CImageHelperBase::CheckNormalFile(LPCTSTR pszImageFilename, ImageIn return eIMAGE_ERROR_BAD_SIZE; } - pImageType = Detect(pImageInfo->pImageBuffer, dwSize, szExt, dwOffset, pImageInfo->bWriteProtected, pImageInfo->pTrackMap, pImageInfo->optimalBitTiming); + pImageType = Detect(pImageInfo->pImageBuffer, dwSize, szExt, dwOffset, pImageInfo->bWriteProtected, pImageInfo->pTrackMap, pImageInfo->optimalBitTiming, pImageInfo->maxNibblesPerTrack); if (bTempDetectBuffer) { delete [] pImageInfo->pImageBuffer; @@ -1746,11 +1747,13 @@ CDiskImageHelper::CDiskImageHelper(void) : m_vecImageTypes.push_back( new CWOZ2Image ); } -CImageBase* CDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming) +CImageBase* CDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, + bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming, UINT& maxNibblesPerTrack) { dwOffset = 0; m_MacBinaryHelper.DetectHdr(pImage, dwSize, dwOffset); m_Result2IMG = m_2IMGHelper.DetectHdr(pImage, dwSize, dwOffset); + maxNibblesPerTrack = NIBBLES_PER_TRACK; // Start with the default size (for all types). May get changed below. // CALL THE DETECTION FUNCTIONS IN ORDER, LOOKING FOR A MATCH eImageType imageType = eImageUNKNOWN; @@ -1802,6 +1805,7 @@ CImageBase* CDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* p writeProtected = true; optimalBitTiming = m_WOZHelper.GetOptimalBitTiming(); + maxNibblesPerTrack = m_WOZHelper.GetMaxNibblesPerTrack(); } else { @@ -1873,7 +1877,8 @@ CHardDiskImageHelper::CHardDiskImageHelper(void) : m_vecImageTypes.push_back( new CHDVImage ); } -CImageBase* CHardDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming) +CImageBase* CHardDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, + bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming, UINT& maxNibblesPerTrack) { dwOffset = 0; m_Result2IMG = m_2IMGHelper.DetectHdr(pImage, dwSize, dwOffset); @@ -1905,6 +1910,7 @@ CImageBase* CHardDiskImageHelper::Detect(LPBYTE pImage, DWORD dwSize, const TCHA pTrackMap = 0; // TODO: WOZ optimalBitTiming = 0; // TODO: WOZ + maxNibblesPerTrack = 0; // TODO return pImageType; } diff --git a/source/DiskImageHelper.h b/source/DiskImageHelper.h index 039a675c..f2b35441 100644 --- a/source/DiskImageHelper.h +++ b/source/DiskImageHelper.h @@ -37,6 +37,7 @@ struct ImageInfo BYTE* pImageBuffer; BYTE* pTrackMap; // WOZ only BYTE optimalBitTiming; // WOZ only + UINT maxNibblesPerTrack; ImageInfo(); }; @@ -202,6 +203,7 @@ public: eDetectResult ProcessChunks(const LPBYTE pImage, const DWORD dwImageSize, DWORD& dwOffset, BYTE*& pTrackMap); bool IsWriteProtected(void) { return m_pInfo->v1.writeProtected == 1; } BYTE GetOptimalBitTiming(void) { return (m_pInfo->v1.version == 1) ? CWOZHelper::InfoChunkv2::optimalBitTiming5_25 : m_pInfo->optimalBitTiming; } + UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v1.version == 1) ? CWOZHelper::WOZ1_TRACK_SIZE : m_pInfo->largestTrack*CWOZHelper::BLOCK_SIZE; } static const UINT32 ID1_WOZ1 = '1ZOW'; // 'WOZ1' static const UINT32 ID1_WOZ2 = '2ZOW'; // 'WOZ2' @@ -218,6 +220,7 @@ public: static const UINT32 WOZ1_TRACK_SIZE = 6656; // 0x1A00 static const UINT32 WOZ1_TRK_OFFSET = 6646; static const UINT32 EMPTY_TRACK_SIZE = 6400; + static const UINT32 BLOCK_SIZE = 512; struct TRKv1 { @@ -304,7 +307,7 @@ public: ImageError_e Open(LPCTSTR pszImageFilename, ImageInfo* pImageInfo, const bool bCreateIfNecessary, std::string& strFilenameInZip); void Close(ImageInfo* pImageInfo, const bool bDeleteFile); - virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming) = 0; + virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming, UINT& maxNibblesPerTrack) = 0; virtual CImageBase* GetImageForCreation(const TCHAR* pszExt, DWORD* pCreateImageSize) = 0; virtual UINT GetMaxImageSize(void) = 0; virtual UINT GetMinDetectSize(const UINT uImageSize, bool* pTempDetectBuffer) = 0; @@ -349,7 +352,7 @@ public: CDiskImageHelper(void); virtual ~CDiskImageHelper(void) {} - virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming); + virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming, UINT& maxNibblesPerTrack); virtual CImageBase* GetImageForCreation(const TCHAR* pszExt, DWORD* pCreateImageSize); virtual UINT GetMaxImageSize(void); virtual UINT GetMinDetectSize(const UINT uImageSize, bool* pTempDetectBuffer); @@ -375,7 +378,7 @@ public: CHardDiskImageHelper(void); virtual ~CHardDiskImageHelper(void) {} - virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming); + virtual CImageBase* Detect(LPBYTE pImage, DWORD dwSize, const TCHAR* pszExt, DWORD& dwOffset, bool& writeProtected, BYTE*& pTrackMap, BYTE& optimalBitTiming, UINT& maxNibblesPerTrack); virtual CImageBase* GetImageForCreation(const TCHAR* pszExt, DWORD* pCreateImageSize); virtual UINT GetMaxImageSize(void); virtual UINT GetMinDetectSize(const UINT uImageSize, bool* pTempDetectBuffer); diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp index 0d73b781..4cc891e5 100644 --- a/source/YamlHelper.cpp +++ b/source/YamlHelper.cpp @@ -237,8 +237,10 @@ void YamlHelper::MakeAsciiToHexTable(void) m_AsciiToHex[i] = i - 'a' + 0xA; } -void YamlHelper::LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize) +UINT YamlHelper::LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize) { + UINT bytes = 0; + for (MapYaml::iterator it = mapYaml.begin(); it != mapYaml.end(); ++it) { const char* pKey = it->first.c_str(); @@ -268,10 +270,13 @@ void YamlHelper::LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_ throw std::string("Memory: hex data contains illegal character on line address: " + it->first); *pDst++ = (ah<<4) | al; + bytes++; } } mapYaml.clear(); + + return bytes; } //------------------------------------- @@ -370,9 +375,9 @@ double YamlLoadHelper::LoadDouble(const std::string key) return strtod(value.c_str(), NULL); } -void YamlLoadHelper::LoadMemory(const LPBYTE pMemBase, const size_t size) +UINT YamlLoadHelper::LoadMemory(const LPBYTE pMemBase, const size_t size) { - m_yamlHelper.LoadMemory(*m_pMapYaml, pMemBase, size); + return m_yamlHelper.LoadMemory(*m_pMapYaml, pMemBase, size); } //------------------------------------- diff --git a/source/YamlHelper.h b/source/YamlHelper.h index f306c0a1..b4bacce1 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -48,7 +48,7 @@ private: void GetNextEvent(bool bInMap = false); int ParseMap(MapYaml& mapYaml); std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound); - void LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); + UINT LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); bool GetSubMap(MapYaml** mapYaml, const std::string key); void GetMapRemainder(std::string& mapName, MapYaml& mapYaml); @@ -99,7 +99,7 @@ public: std::string LoadString(const std::string& key); float LoadFloat(const std::string key); double LoadDouble(const std::string key); - void LoadMemory(const LPBYTE pMemBase, const size_t size); + UINT LoadMemory(const LPBYTE pMemBase, const size_t size); bool GetSubMap(const std::string key) {