WOZ: Support large tracks (fixes #745)

This commit is contained in:
tomcw 2019-12-31 12:07:45 +00:00
parent 183ec2bc8c
commit a28803cbf9
8 changed files with 53 additions and 28 deletions

View File

@ -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<BYTE> track(NIBBLES_PER_TRACK);
std::vector<BYTE> 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)

View File

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

View File

@ -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 ];

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
{