mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-23 00:34:22 +00:00
add a utility to convert NDIF disk images (WIP)
This commit is contained in:
parent
057768eedf
commit
14570ffa1f
@ -77,4 +77,5 @@ add_subdirectory(ConvertObj)
|
||||
add_subdirectory(PEFTools)
|
||||
add_subdirectory(Elf2Mac)
|
||||
add_subdirectory(LaunchAPPL)
|
||||
add_subdirectory(ConvertDiskImage)
|
||||
endif()
|
||||
|
2
ConvertDiskImage/CMakeLists.txt
Normal file
2
ConvertDiskImage/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
add_executable(ConvertDiskImage ConvertDiskImage.cc)
|
||||
target_link_libraries(ConvertDiskImage ResourceFiles)
|
130
ConvertDiskImage/ConvertDiskImage.cc
Normal file
130
ConvertDiskImage/ConvertDiskImage.cc
Normal file
@ -0,0 +1,130 @@
|
||||
#include <ResourceFile.h>
|
||||
#include <BinaryIO.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
void decompreassADC(std::vector<uint8_t>& outbuf, const std::vector<uint8_t>& inbuf)
|
||||
{
|
||||
outbuf.reserve(0x40000);
|
||||
auto p = inbuf.begin();
|
||||
|
||||
while(p != inbuf.end())
|
||||
{
|
||||
auto cmd = *p++;
|
||||
if(cmd & 0x80)
|
||||
{
|
||||
int n = (cmd & 0x7f) + 1;
|
||||
outbuf.insert(outbuf.end(), p, p + n);
|
||||
p += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
int off;
|
||||
int n;
|
||||
if(cmd & 0x40)
|
||||
{
|
||||
n = (cmd & 0x3f) + 4;
|
||||
off = *p++ << 8;
|
||||
off |= *p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = ((cmd & 0x3c) >> 2) + 3;
|
||||
off = ((cmd & 3) << 8) | *p++;
|
||||
}
|
||||
++off;
|
||||
|
||||
outbuf.reserve(outbuf.size() + n);
|
||||
outbuf.insert(outbuf.end(), outbuf.end() - off, outbuf.end() - off + n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if(argc != 3)
|
||||
{
|
||||
std::cerr << "Usage: ConvertDiskImage input.img output.dsk\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
ResourceFile file(argv[1]);
|
||||
if(!file.read())
|
||||
{
|
||||
std::cerr << "Couldn't read input.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::istringstream bcem(file.resources.resources[ResRef("bcem",128)].getData());
|
||||
std::istringstream ndif(file.data);
|
||||
std::ofstream output(argv[2], std::ios::binary | std::ios::trunc);
|
||||
|
||||
word(bcem);
|
||||
word(bcem);
|
||||
for(int i = 0; i<64; i++)
|
||||
byte(bcem); // volume name
|
||||
|
||||
int blockCount [[maybe_unused]] = longword(bcem);
|
||||
int blockSize = longword(bcem) & ~1; // ???
|
||||
std::cout << blockCount << " blocks of " << blockSize << std::endl;
|
||||
int hhBSZeroOffset [[maybe_unused]] = longword(bcem);
|
||||
int checksum [[maybe_unused]] = longword(bcem);
|
||||
int unknown1 [[maybe_unused]] = longword(bcem);
|
||||
int unknown2 [[maybe_unused]] = longword(bcem);
|
||||
int unknown3 [[maybe_unused]] = longword(bcem);
|
||||
|
||||
for(int i = 0; i < 7; i++)
|
||||
longword(bcem); // reserved
|
||||
|
||||
int nChunks = longword(bcem);
|
||||
|
||||
std::vector<uint8_t> inbuf;
|
||||
std::vector<uint8_t> outbuf;
|
||||
|
||||
for(int i = 0; i < nChunks; i++)
|
||||
{
|
||||
unsigned tmp = longword(bcem);
|
||||
unsigned dstStartOffset = blockSize * (tmp >> 8);
|
||||
unsigned compression = tmp & 0xFF;
|
||||
unsigned offset = longword(bcem);
|
||||
unsigned size = longword(bcem);
|
||||
|
||||
std::cout << std::hex << "starting at " << dstStartOffset << " from " << offset << " size " << size << " compression " << compression << std::endl;
|
||||
|
||||
if(output.tellp() < dstStartOffset)
|
||||
{
|
||||
std::cout << std::hex << "zero bytes from " << output.tellp() << std::endl;
|
||||
|
||||
output.seekp(dstStartOffset - 1);
|
||||
output.put(0);
|
||||
}
|
||||
|
||||
inbuf.clear();
|
||||
outbuf.clear();
|
||||
|
||||
inbuf.resize(size);
|
||||
ndif.seekg(offset);
|
||||
ndif.read((char*)inbuf.data(), size);
|
||||
|
||||
switch(compression)
|
||||
{
|
||||
case 0:
|
||||
case 0xFF:
|
||||
break;
|
||||
case 2:
|
||||
outbuf = std::move(inbuf);
|
||||
break;
|
||||
|
||||
case 0x83:
|
||||
decompreassADC(outbuf, inbuf);
|
||||
break;
|
||||
}
|
||||
|
||||
output.write((char*)outbuf.data(), outbuf.size());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user