Fix OMF version confusion

VERSION=0/1/2 corresponds, simply, to v0/v1/v2, where v0 was only
used for some older 8-bit Orca/M stuff.  v2.1 can be detected by
looking for the optional "tempOrg" field.

Also, allow the disk version number to be set to zero in 2IMG images.
This commit is contained in:
Andy McFadden 2020-06-25 14:12:29 -07:00
parent e625ab5f3a
commit e5ac0ac631
3 changed files with 24 additions and 13 deletions

View File

@ -99,7 +99,7 @@ void TwoImgPropsDialog::DoDataExchange(CDataExchange* pDX)
fpHeader->fFlags |= (dosVolNum & TwoImgHeader::kDOSVolumeMask); fpHeader->fFlags |= (dosVolNum & TwoImgHeader::kDOSVolumeMask);
CString appStr, errMsg; CString appStr, errMsg;
if (dosVolNum < 1 || dosVolNum > 254) { if (dosVolNum < 0 || dosVolNum > 254) {
CheckedLoadString(&appStr, IDS_MB_APP_NAME); CheckedLoadString(&appStr, IDS_MB_APP_NAME);
CheckedLoadString(&errMsg, IDS_VALID_VOLNAME_DOS); CheckedLoadString(&errMsg, IDS_VALID_VOLNAME_DOS);
MessageBox(errMsg, appStr, MB_OK); MessageBox(errMsg, appStr, MB_OK);

View File

@ -937,9 +937,10 @@ void ReformatDisasm16::PrintHeader(const OMFSegmentHeader* pSegHdr,
const char* versStr; const char* versStr;
switch (pSegHdr->GetVersion()) { switch (pSegHdr->GetVersion()) {
case 0: versStr = "1.0"; break; case 0: versStr = "0.0"; break;
case 1: versStr = "2.0"; break; case 1: versStr = "1.0"; break;
case 2: versStr = "2.1"; break; case 2: versStr = "2.0"; break;
case 0x82: versStr = "2.1"; break;
default: versStr = "(unknown)"; break; default: versStr = "(unknown)"; break;
} }
@ -1058,8 +1059,9 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
return false; return false;
} }
fRevision = 0;
if (fVersion == 0) { if (fVersion == 0) {
/* unpack OMF v1.0 */ /* unpack OMF v0.0 (not actually used for 16-bit code?) */
if (srcLen < kV0HdrMinSize) if (srcLen < kV0HdrMinSize)
return false; return false;
@ -1086,7 +1088,7 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
else else
fDispData = fDispName + fLabLen; fDispData = fDispName + fLabLen;
} else if (fVersion == 1) { } else if (fVersion == 1) {
/* unpack OMF v2.0 */ /* unpack OMF v1.0 */
if (srcLen < kV1HdrMinSize) if (srcLen < kV1HdrMinSize)
return false; return false;
fBlockCnt = Get32LE(srcBuf + 0x00); fBlockCnt = Get32LE(srcBuf + 0x00);
@ -1124,7 +1126,7 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
fKind = 0; fKind = 0;
fTempOrg = 0; fTempOrg = 0;
} else { } else {
/* unpack OMF v2.1 */ /* unpack OMF v2.x */
if (srcLen < kV2HdrMinSize) if (srcLen < kV2HdrMinSize)
return false; return false;
fByteCnt = Get32LE(srcBuf + 0x00); fByteCnt = Get32LE(srcBuf + 0x00);
@ -1144,7 +1146,13 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
fEntry = Get32LE(srcBuf + 0x24); fEntry = Get32LE(srcBuf + 0x24);
fDispName = Get16LE(srcBuf + 0x28); fDispName = Get16LE(srcBuf + 0x28);
fDispData = Get16LE(srcBuf + 0x2a); fDispData = Get16LE(srcBuf + 0x2a);
fTempOrg = Get32LE(srcBuf + 0x2c); if (fDispName > 0x2c) {
// v2.1 adds a 4-byte "tempOrg" field
fTempOrg = Get32LE(srcBuf + 0x2c);
fRevision = 1;
} else {
fTempOrg = 0;
}
fBlockCnt = 0; fBlockCnt = 0;
fType = 0; fType = 0;
@ -1192,6 +1200,8 @@ bool OMFSegmentHeader::Unpack(const uint8_t* srcBuf, long srcLen, int fileType)
fLoadName[kLoadNameLen] = '\0'; fLoadName[kLoadNameLen] = '\0';
segName += kLoadNameLen; segName += kLoadNameLen;
} else {
fLoadName[0] = '\0';
} }
if (fLabLen == 0) { if (fLabLen == 0) {

View File

@ -227,7 +227,7 @@ public:
kTypePathName = 0x04, kTypePathName = 0x04,
kTypeLibraryDict = 0x08, kTypeLibraryDict = 0x08,
kTypeInit = 0x10, kTypeInit = 0x10,
kTypeAbsoluteBank = 0x11, kTypeAbsoluteBank = 0x11, // v1.0 only
kTypeDPStack = 0x12, kTypeDPStack = 0x12,
} SegmentType; } SegmentType;
typedef enum SegmentFlag { typedef enum SegmentFlag {
@ -241,7 +241,7 @@ public:
kFlagDynamic, kFlagDynamic,
} SegmentFlag; } SegmentFlag;
uint8_t GetVersion(void) const { return fVersion; } uint8_t GetVersion(void) const { return fVersion + (fRevision << 7); }
uint32_t GetSegmentLen(void) const { return fByteCnt; } uint32_t GetSegmentLen(void) const { return fByteCnt; }
SegmentType GetSegmentType(void) const; SegmentType GetSegmentType(void) const;
bool GetSegmentFlag(SegmentFlag flag) const; bool GetSegmentFlag(SegmentFlag flag) const;
@ -254,11 +254,11 @@ public:
// some of these must be public in VC++6.0 // some of these must be public in VC++6.0
enum { enum {
kMaxVersion = 2, // v0/1/2 == OMF 1.0 / 2.0 / 2.1 kMaxVersion = 2, // v0/1/2 == OMF 0.0 / 1.0 / 2.x
kLoadNameLen = 10, kLoadNameLen = 10,
kV0HdrMinSize = 0x25, kV0HdrMinSize = 0x25,
kV1HdrMinSize = 0x2c + kLoadNameLen, kV1HdrMinSize = 0x2c + kLoadNameLen,
kV2HdrMinSize = 0x30 + kLoadNameLen, kV2HdrMinSize = kV1HdrMinSize, // 2.1 is slightly larger; handle that elsewhere
kHdrMinSize = kV0HdrMinSize, // smallest of the three kHdrMinSize = kV0HdrMinSize, // smallest of the three
kExpectedNumLen = 4, kExpectedNumLen = 4,
kExpectedBankSize = 65536, kExpectedBankSize = 65536,
@ -277,13 +277,14 @@ private:
} }
uint32_t fBlockCnt; // v0/v1 uint32_t fBlockCnt; // v0/v1
uint32_t fByteCnt; // v2 uint32_t fByteCnt; // [v1]/v2
uint32_t fResSpc; uint32_t fResSpc;
uint32_t fLength; uint32_t fLength;
uint8_t fType; // v0/v1 uint8_t fType; // v0/v1
uint8_t fLabLen; uint8_t fLabLen;
uint8_t fNumLen; // (always 4) uint8_t fNumLen; // (always 4)
uint8_t fVersion; // (0, 1, or 2) uint8_t fVersion; // (0, 1, or 2)
uint8_t fRevision; // fictitious field; holds 0 or 1
uint32_t fBankSize; // (always 65536) uint32_t fBankSize; // (always 65536)
uint16_t fKind; // v2 uint16_t fKind; // v2
uint32_t fOrg; uint32_t fOrg;