WOZHelper: ValidateTMAPandFLUX()

This commit is contained in:
tomcw 2023-09-10 16:39:11 +01:00
parent be427a6a30
commit 035120dd57
2 changed files with 67 additions and 27 deletions

View File

@ -1502,14 +1502,14 @@ eDetectResult CWOZHelper::ProcessChunks(ImageInfo* pImageInfo, DWORD& dwOffset)
switch(chunkId)
{
case INFO_CHUNK_ID:
m_pInfo = (InfoChunkv2*)pImage32;
if (m_pInfo->v1.diskType != InfoChunk::diskType5_25)
m_pInfo = (InfoChunkv3*)pImage32;
if (m_pInfo->v2.v1.diskType != InfoChunk::diskType5_25)
return eMismatch;
#ifdef _DEBUG
if (m_pInfo->v1.version >= 3)
if (m_pInfo->v2.v1.version >= 3)
{
InfoChunkv3* pInfoV3 = (InfoChunkv3*)pImage32;
LogOutput("WOZ: Largest Flux Track = %d\n", pInfoV3->largestFluxTrack);
LogOutput("WOZ: Largest Flux Track (in blocks) = %d\n", pInfoV3->largestFluxTrack);
}
break;
#endif
@ -1519,7 +1519,8 @@ eDetectResult CWOZHelper::ProcessChunks(ImageInfo* pImageInfo, DWORD& dwOffset)
case TRKS_CHUNK_ID:
dwOffset = pImageInfo->uOffset = pImageInfo->uImageSize - imageSizeRemaining; // offset into image of track data
break;
case FLUX_CHUNK_ID: // WOZ v3 (todo)
case FLUX_CHUNK_ID: // WOZ v2.1 (todo)
pImageInfo->pWOZTrackMapFlux = (BYTE*)pImage32;
break;
case WRIT_CHUNK_ID: // WOZ v2 (optional)
break;
@ -1537,9 +1538,46 @@ eDetectResult CWOZHelper::ProcessChunks(ImageInfo* pImageInfo, DWORD& dwOffset)
return eMismatch;
}
ValidateTMAPandFLUX(pImageInfo);
return eMatch;
}
bool CWOZHelper::ValidateTMAPandFLUX(ImageInfo* pImageInfo)
{
if (pImageInfo->pWOZTrackMap == NULL)
return false;
if (pImageInfo->pWOZTrackMapFlux == NULL)
return true;
if ( (m_pInfo->v2.v1.version < 3) || // // must be INFO v3 or more for FLUX tmap
(!m_pInfo->fluxBlock || !m_pInfo->largestFluxTrack) ) // both fluxBlock and largestFluxTrack must be non-zero
{
LogOutput("WOZ image with FLUX invalid\n");
pImageInfo->pWOZTrackMapFlux = NULL;
return false;
}
// We have both TMAP and FLUX tmaps so check there's no valid (non-0xFF) entries in both.
BYTE* pTMAP = (BYTE*)pImageInfo->pWOZTrackMap;
BYTE* pFLUX = (BYTE*)pImageInfo->pWOZTrackMapFlux;
// LogOutput("----: TMAP FLUX\n");
for (UINT i = 0; i < MAX_QUARTER_TRACKS_5_25; i++, pTMAP++, pFLUX++)
{
// LogOutput("%04d: %02X %02X\n", i, *pTMAP, *pFLUX);
if (*pTMAP != TMAP_TRACK_EMPTY && *pFLUX != TMAP_TRACK_EMPTY)
{
LogOutput("WOZ image with FLUX not created properly (quarter track: %d)\n", i);
*pTMAP = TMAP_TRACK_EMPTY; // WOZ v2.1 spec says to use FLUX
}
}
return true;
}
//-----------------------------------------------------------------------------
// NB. Of the 6 cases (floppy/harddisk x gzip/zip/normal) only harddisk-normal isn't read entirely to memory
@ -2251,18 +2289,18 @@ BYTE* CWOZHelper::CreateEmptyDisk(DWORD& size)
pWOZ->infoHdr.id = INFO_CHUNK_ID;
pWOZ->infoHdr.size = (BYTE*)&pWOZ->tmapHdr - (BYTE*)&pWOZ->info;
_ASSERT(pWOZ->infoHdr.size == INFO_CHUNK_SIZE);
pWOZ->info.v1.version = 2;
pWOZ->info.v1.diskType = InfoChunk::diskType5_25;
pWOZ->info.v1.cleaned = 1;
pWOZ->info.v2.v1.version = 2;
pWOZ->info.v2.v1.diskType = InfoChunk::diskType5_25;
pWOZ->info.v2.v1.cleaned = 1;
std::string creator = "AppleWin v" + g_VERSIONSTRING;
memset(&pWOZ->info.v1.creator[0], ' ', sizeof(pWOZ->info.v1.creator));
memcpy(&pWOZ->info.v1.creator[0], creator.c_str(), creator.size()); // don't include null
pWOZ->info.diskSides = 1;
pWOZ->info.bootSectorFormat = bootUnknown; // could be INIT'd to 13 or 16 sector
pWOZ->info.optimalBitTiming = InfoChunkv2::optimalBitTiming5_25;
pWOZ->info.compatibleHardware = 0; // unknown
pWOZ->info.requiredRAM = 0; // unknown
pWOZ->info.largestTrack = TRK_DEFAULT_BLOCK_COUNT_5_25; // unknown - but use default
memset(&pWOZ->info.v2.v1.creator[0], ' ', sizeof(pWOZ->info.v2.v1.creator));
memcpy(&pWOZ->info.v2.v1.creator[0], creator.c_str(), creator.size()); // don't include null
pWOZ->info.v2.diskSides = 1;
pWOZ->info.v2.bootSectorFormat = bootUnknown; // could be INIT'd to 13 or 16 sector
pWOZ->info.v2.optimalBitTiming = InfoChunkv2::optimalBitTiming5_25;
pWOZ->info.v2.compatibleHardware = 0; // unknown
pWOZ->info.v2.requiredRAM = 0; // unknown
pWOZ->info.v2.largestTrack = TRK_DEFAULT_BLOCK_COUNT_5_25; // unknown - but use default
// TMAP
ASSERT_OFFSET(tmapHdr, 80);

View File

@ -37,6 +37,7 @@ struct ImageInfo
UINT uNumTracks;
BYTE* pImageBuffer;
BYTE* pWOZTrackMap; // WOZ only (points into pImageBuffer)
BYTE* pWOZTrackMapFlux; // WOZ only (points into pImageBuffer) (from WOZv2.1)
BYTE optimalBitTiming; // WOZ only
BYTE bootSectorFormat; // WOZ only
UINT maxNibblesPerTrack;
@ -209,12 +210,13 @@ public:
virtual eDetectResult DetectHdr(LPBYTE& pImage, DWORD& dwImageSize, DWORD& dwOffset) { _ASSERT(0); return eMismatch; }
virtual UINT GetMaxHdrSize(void) { return sizeof(WOZHeader); }
eDetectResult ProcessChunks(ImageInfo* pImageInfo, DWORD& dwOffset);
bool IsWriteProtected(void) { return m_pInfo->v1.writeProtected == 1; }
BYTE GetOptimalBitTiming(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->optimalBitTiming : InfoChunkv2::optimalBitTiming5_25; }
UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->largestTrack*CWOZHelper::BLOCK_SIZE : WOZ1_TRACK_SIZE; }
BYTE GetBootSectorFormat(void) { return (m_pInfo->v1.version >= 2) ? m_pInfo->bootSectorFormat : bootUnknown; }
bool IsWriteProtected(void) { return m_pInfo->v2.v1.writeProtected == 1; }
BYTE GetOptimalBitTiming(void) { return (m_pInfo->v2.v1.version >= 2) ? m_pInfo->v2.optimalBitTiming : InfoChunkv2::optimalBitTiming5_25; }
UINT GetMaxNibblesPerTrack(void) { return (m_pInfo->v2.v1.version >= 2) ? m_pInfo->v2.largestTrack*CWOZHelper::BLOCK_SIZE : WOZ1_TRACK_SIZE; }
BYTE GetBootSectorFormat(void) { return (m_pInfo->v2.v1.version >= 2) ? m_pInfo->v2.bootSectorFormat : bootUnknown; }
void InvalidateInfo(void) { m_pInfo = NULL; }
BYTE* CreateEmptyDisk(DWORD& size);
bool ValidateTMAPandFLUX(ImageInfo* pImageInfo);
#if _DEBUG
BYTE* CreateEmptyDiskv1(DWORD& size);
#endif
@ -267,9 +269,9 @@ public:
struct TRKv2
{
UINT16 startBlock; // relative to start of file
UINT16 startBlock; // First block of BITS (or flux) data, relative to start of file
UINT16 blockCount; // number of blocks for this BITS data
UINT32 bitCount;
UINT32 bitCount; // NB. From WOZv2.1 for flux tracks this is a byte count
};
struct Trks
@ -284,8 +286,8 @@ private:
static const UINT32 TRKS_CHUNK_ID = 'SKRT'; // 'TRKS'
static const UINT32 WRIT_CHUNK_ID = 'TIRW'; // 'WRIT' - WOZv2
static const UINT32 META_CHUNK_ID = 'ATEM'; // 'META'
static const UINT32 FLUX_CHUNK_ID = 'XULF'; // 'FLUX' - WOZv3
static const UINT32 INFO_CHUNK_SIZE = 60; // Fixed size for both WOZv1 & WOZv2
static const UINT32 FLUX_CHUNK_ID = 'XULF'; // 'FLUX' - WOZv2.1
static const UINT32 INFO_CHUNK_SIZE = 60; // Fixed size for both WOZv1 & WOZv2.1
struct InfoChunk
{
@ -322,7 +324,7 @@ private:
UINT16 largestFluxTrack; // in blocks (512 bytes)
};
InfoChunkv2* m_pInfo; // NB. image-specific - only valid during Detect(), which calls InvalidateInfo() when done
InfoChunkv3* m_pInfo; // NB. image-specific - only valid during Detect(), which calls InvalidateInfo() when done
//
@ -331,8 +333,8 @@ private:
WOZHeader hdr;
WOZChunkHdr infoHdr;
InfoChunkv2 info;
BYTE infoPadding[INFO_CHUNK_SIZE-sizeof(InfoChunkv2)];
InfoChunkv3 info;
BYTE infoPadding[INFO_CHUNK_SIZE-sizeof(InfoChunkv3)];
WOZChunkHdr tmapHdr;
Tmap tmap;