1
0
mirror of synced 2026-05-05 07:23:49 +00:00

Inial population of repository.

This commit is contained in:
Andras Tantos
2020-09-09 15:11:45 -07:00
parent 2989973ef5
commit 95b2381d05
1323 changed files with 875486 additions and 15 deletions

View File

@@ -0,0 +1,35 @@
#################################################################################
### MODE: determines what compiler flags to use
### SYSTEM: determines the intermediate and final file directory names (for now)
### DEFINES: list of predefined macros to pass to the compiler
### INC_DIRS: list of include paths to pass to the compiler
### DEP_INC_DIRS: list of include paths to search for dependencies in
### LIB_DIRS: list of library paths to pass to the linker
### TARGET_TYPE: determines whether to build executables or libraries
### SOURCES: list of source (c++) files
### SRC_DIRS: list of source paths. Needed to generate implicit rules
### SOURCE_LIBS: list of locally built libs (they are included as a dependency)
### LINK_LIBS: list of libraries to link againsg on top of SOURCE_LIBS
### TARGETS: list of target final targets (library names or executable files)
ifndef MODE
MODE=release
#MODE=debug
endif
include ../common.mak
TARGET_TYPE = EXECUTABLE
SOURCES =
SOURCES += dataset_extractor.cpp
SOURCE_LIBS =
LINK_LIBS =
LINK_LIBS += $(COMMON_LIBS)
TARGETS =
TARGETS += dataset_extractor
include ../engine.mak

View File

@@ -0,0 +1,307 @@
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "utils.h"
#include <sstream>
#include <boost/filesystem.hpp>
// Normal sequences:
// BCW - if we're not in a dataset, this starts a dataset
// - if we're not in a file, this starts a file
// - if we're not in a record, this starts a record
// - otherwise, this is just a continuation of the current record
// EOR - if we're in a record, it ends the current record
// - otherwise it denotes a NULL record
// EOF - if we're in a file, it ends the current file
// - otherwise it denotes a NULL file
// EOD - if we're in a dataset, it ends the dataset
// - otherwise it denotes a NULL dataset
//
// Ending a file without ending a record is invalid, except for a NULL file
// Ending a dataset without ending a file is invalid
//
// If an EOR is followed by a BCW, that's fine, this
// simply means that the data for the next record is after
// the BCW. This technique can be used to skip over
// certain sections of a dataset: since the forward index
// of an EOR or EOF points to a BCW, the region between the
// the two control words is assumed to not contain data
//
// There is some RLL compression for 'blank fields' whatever that means
// See 2240011R part 1 2-6 - this seems like it have been removed later
//
// There are some new bigs that are not in the original description
// See SR-0011P 2-15
//
// So, to add a file to the end:
// 1. Remove the EOD
// 2. Add the file, starting with a BCW
// 3. Terminate with an EOD
//
// To add a file to the beginning:
// 1. Create the file as normal, starting with a BCW
// 2. Append the old dataset to it
//
// To add a file at an arbitrary position
// A. If the EOF of the previous file points to an EOR (that is the first record of the next file
// 1. Patch up EOF to point to immediately after itself
// 2. Add file as normal, starting with a BCW
// 3. Patch up our EOF to point to the first EOR of the old file
// 4. Add the rest of the Dataset
// B. If the EOF of the previous file points to a BCW
// 1. Add the file as normal, starting with a BCW
// 2. Make sure our EOF points immediately after itself
// 2. Add the rest of the dataset
//
// To remove the first file
//
enum CtrlWordType_e {
CtrlWordType_BCW = 000,
CtrlWordType_EOR = 010,
CtrlWordType_EOF = 016,
CtrlWordType_EOD = 017,
CtrlWordType_UNK = 020
};
// Common fields
CtrlWordType_e CtrlWord_GetType(uint64_t aCtrlWord) {
uint8_t CtrlType = ((uint8_t *)(&aCtrlWord))[7] >> 4;
switch (CtrlType) {
case CtrlWordType_BCW: return (CtrlWordType_e)CtrlType;
case CtrlWordType_EOR: return (CtrlWordType_e)CtrlType;
case CtrlWordType_EOF: return (CtrlWordType_e)CtrlType;
case CtrlWordType_EOD: return (CtrlWordType_e)CtrlType;
default: return CtrlWordType_UNK;
}
}
bool CtrlWord_GetBadData(uint64_t aCtrlWord) {
// get bit 52 out
return ((aCtrlWord >> 52) & 1) == 0 ? false: true;
}
uint32_t CtrlWord_GetForwardWordIdx(uint64_t aCtrlWord) {
uint32_t Lower = (uint32_t)aCtrlWord;
return Lower & 0x1ff;
}
// BCW fields
uint32_t CtrlWord_GetBlockNumber(uint64_t aCtrlWord) {
uint32_t Lower = (uint32_t)aCtrlWord;
Lower >>= 9;
return Lower;
}
// EOR,EOF,EOD fields
uint32_t CtrlWord_GetUnusedBitCnt(uint64_t aCtrlWord) {
return ((aCtrlWord >> 54) & 63);
}
bool CtrlWord_GetTransparent(uint64_t aCtrlWord) {
// get bit 53 out
uint8_t Byte = ((uint8_t *)(&aCtrlWord))[6];
return (Byte & 0x20) == 0 ? false: true;
}
bool CtrlWord_GetSkipRemainderSector(uint64_t aCtrlWord) {
// get bit 51 out
uint8_t Byte = ((uint8_t *)(&aCtrlWord))[6];
return (Byte & 0x08) == 0 ? false: true;
}
uint32_t CtrlWord_GetPreviousFileIdx(uint64_t aCtrlWord) {
return uint32_t(GetBitsReverse(aCtrlWord, 20, 39));
}
uint32_t CtrlWord_GetPreviousRecordIdx(uint64_t aCtrlWord) {
return uint32_t(GetBitsReverse(aCtrlWord, 40, 54));
}
std::string PrintCtrlWord(uint64_t aCtrlWord) {
std::stringstream Str;
switch (CtrlWord_GetType(aCtrlWord)) {
case CtrlWordType_BCW: Str << "BCW: "; break;
case CtrlWordType_EOR: Str << "EOR: "; break;
case CtrlWordType_EOF: Str << "EOF: "; break;
case CtrlWordType_EOD: Str << "EOD: "; break;
default: Str << "UNK: "; break;
}
Str << "Forward word IDX: " << DecPrinter(CtrlWord_GetForwardWordIdx(aCtrlWord), 5) << " ";
switch (CtrlWord_GetType(aCtrlWord)) {
case CtrlWordType_BCW:
Str << "Block Number: " << CtrlWord_GetBlockNumber(aCtrlWord) << " ";
break;
case CtrlWordType_EOR:
case CtrlWordType_EOF:
case CtrlWordType_EOD:
Str << "Unused bit count: " << DecPrinter(CtrlWord_GetUnusedBitCnt(aCtrlWord),2) << " ";
Str << "Prev file idx: " << HexPrinter(CtrlWord_GetPreviousFileIdx(aCtrlWord),7) << " ";
Str << "Prev record idx: " << HexPrinter(CtrlWord_GetPreviousRecordIdx(aCtrlWord),6) << " ";
Str << (CtrlWord_GetTransparent(aCtrlWord) ? "TRANS ":"");
Str << (CtrlWord_GetSkipRemainderSector(aCtrlWord) ? "SKIP ":"");
break;
default: Str << "UNK: "; break;
}
Str << (CtrlWord_GetBadData(aCtrlWord) ? "BAD":"");
return Str.str();
}
int main(int argc, char* argv[])
{
if (argc != 2) {
printf("Usage: %s <image file>\n",argv[0]);
return 1;
}
const char *InFileName = argv[1];
FILE *Input = fopen(InFileName,"rb");
if (Input == nullptr) {
printf("Can't open input file: %s\n", InFileName);
return 1;
}
uint64_t TotalFileSize = boost::filesystem::file_size(InFileName);
const size_t MaxFileSize = 256*1024*1024;
if (TotalFileSize > MaxFileSize) {
printf("Can't use files larger than %uMB\n",unsigned(MaxFileSize/1024/1024));
fclose(Input);
return 1;
}
uint8_t *File = new uint8_t[(size_t)TotalFileSize+1];
if (File == nullptr) {
printf("Not enough memory to allocate buffer for image\n");
fclose(Input);
return 1;
}
size_t Read = fread(File,1,(size_t)TotalFileSize,Input);
fclose(Input);
if (Read != TotalFileSize) {
printf("Can't read file.\n");
return 1;
}
{
size_t Offset = 0;
bool InDataSet = false;
int DataSetCnt = 0;
int FileCnt = 0;
int RecordCnt = 0;
char FileName[255];
int LastSeqCnt = -1;
FILE *OutFile = nullptr;
while (Offset < TotalFileSize) {
uint64_t CtrlWord = SwapBytes(*(uint64_t*)(File+Offset));
int SeqCount;
CtrlWordType_e Type = CtrlWord_GetType(CtrlWord);
std::cout << PrintCtrlWord(CtrlWord) << std::endl;
if (Type == CtrlWordType_UNK) {
printf("Lost track at 0x%08x\n",unsigned(Offset));
break;
}
switch (Type) {
case CtrlWordType_BCW:
SeqCount = (int)CtrlWord_GetBlockNumber(CtrlWord);
if (SeqCount == 0 && InDataSet) {
printf("BCW Start sequence inconsitency at 0x%08x\n",unsigned(Offset));
}
if (SeqCount != LastSeqCnt + 1) {
printf("BCW Sequence inconsitency at 0x%08x\n",unsigned(Offset));
}
if (!InDataSet) {
InDataSet = true;
// New dataset: let's close the old file, and start a new one
FileCnt = 0;
RecordCnt = 0;
}
LastSeqCnt = SeqCount;
break;
case CtrlWordType_EOR:
break;
case CtrlWordType_EOF:
break;
case CtrlWordType_EOD:
break;
default:
printf("Internal error at offset 0x%08x\n",unsigned(Offset));
exit(1);
break;
}
uint32_t DataSize = CtrlWord_GetForwardWordIdx(CtrlWord) * 8;
uint32_t RecordSize = DataSize;
// See what the next control word is and if there's anything to save
uint32_t UnusedBitCnt = 0;
CtrlWordType_e NextType = CtrlWordType_UNK;
if (Type != CtrlWordType_EOD) {
uint64_t NextCtrlWord = SwapBytes(*(uint64_t*)(File+Offset+8+RecordSize));
NextType = CtrlWord_GetType(NextCtrlWord);
if (NextType == CtrlWordType_EOR) UnusedBitCnt = CtrlWord_GetUnusedBitCnt(NextCtrlWord);
}
DataSize -= UnusedBitCnt / 8;
if (DataSize != 0) {
if (OutFile == nullptr) {
sprintf(FileName,"DS%03d_F%03d.dat",DataSetCnt,FileCnt);
OutFile = fopen(FileName,"wb");
if (OutFile == nullptr) {
printf("Can't create file: %s\n",FileName);
return 1;
}
}
size_t Written = fwrite(File+Offset+8,1,DataSize,OutFile);
if (Written != DataSize) {
printf("Can't write to file\n");
return 1;
}
}
switch (NextType) {
case CtrlWordType_BCW:
break;
case CtrlWordType_EOR:
++RecordCnt;
//if (OutFile != nullptr) fclose(OutFile); OutFile = nullptr;
if (OutFile == nullptr) {
printf("EOR encountered with no file at offset 0x%08x\n",unsigned(Offset));
exit(1);
}
fprintf(OutFile,"\n"); // TODO: this should only happen for text files
break;
case CtrlWordType_EOF:
++FileCnt;
RecordCnt = 0;
if (OutFile != nullptr) fclose(OutFile); OutFile = nullptr;
break;
case CtrlWordType_EOD:
++DataSetCnt;
InDataSet = false;
if (OutFile != nullptr) fclose(OutFile); OutFile = nullptr;
LastSeqCnt = -1;
break;
case CtrlWordType_UNK:
if (Type != CtrlWordType_EOD) {
printf("Internal error at offset 0x%08x\n",unsigned(Offset));
exit(1);
}
break;
default:
printf("Internal error at offset 0x%08x\n",unsigned(Offset));
exit(1);
break;
}
Offset += 8 + RecordSize;
if (Type == CtrlWordType_EOD) {
// Jump over to the next data record boundary
Offset = (Offset & 0xfffff000) + 0x1000;
}
}
}
delete[] File;
return 0;
}

View File

@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dataset_extractor", "dataset_extractor.vcxproj", "{B5F8F7C2-6676-4408-AC49-0491C5C660B0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B5F8F7C2-6676-4408-AC49-0491C5C660B0}.Debug|Win32.ActiveCfg = Debug|Win32
{B5F8F7C2-6676-4408-AC49-0491C5C660B0}.Debug|Win32.Build.0 = Debug|Win32
{B5F8F7C2-6676-4408-AC49-0491C5C660B0}.Release|Win32.ActiveCfg = Release|Win32
{B5F8F7C2-6676-4408-AC49-0491C5C660B0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{B5F8F7C2-6676-4408-AC49-0491C5C660B0}</ProjectGuid>
<RootNamespace>dataset_extractor</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v140_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="..\common.props" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Link>
<Profile>true</Profile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<Profile>true</Profile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dataset_extractor.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>