WOZ: Support large tracks (fixes #745)
This commit is contained in:
parent
183ec2bc8c
commit
a28803cbf9
8 changed files with 53 additions and 28 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue