
Сообщение от
valker
Я написал конвертер в sna-формат. Но не выкладывал (сырой он, плюс требует .NET2.0). Ежели нужно, могу выложить.
Дотнету- нет! 
Вот сырец моего конвертора (тока шо написал, еще не проверял).
Не берет пока 128к режим (ибо не знаю пока как раскиданы адреса по страничкам). Компиляется под gnu-gcc, но должен собраться и под виндой и под досом (ничего специфичного).
Имя выходного файла можно задать, иначе оно берется либо из секции 0 или имени входного файла.
Код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
#pragma pack(push, 1)
struct SNA48
{
BYTE i;
WORD hl_;
WORD de_;
WORD bc_;
WORD af_;
WORD hl;
WORD de;
WORD bc;
WORD iy;
WORD ix;
BYTE intstat;
BYTE r;
WORD af;
WORD sp;
BYTE intmode;
BYTE border;
BYTE memory[49152];
};
struct SNA128
{
SNA48 hdr1;
WORD pc;
BYTE port7ffd;
BYTE trdosrom;
BYTE himemory[5 * 16384];
};
#pragma pack(pop)
class FdEnv
{
FdEnv(const FdEnv&);
FdEnv& operator = (const FdEnv&);
public:
FdEnv(FILE* fil) {if (! (file_ = fil)) throw "Cannot open file";}
~FdEnv() {fclose(file_);}
operator FILE* () {return file_;}
private:
FILE* file_;
};
// usage: makesna -o output.sna -v -b0 -r24576 input.s01
int main(int argc, char** argv)
{
SNA128 snapshot;
unsigned verbose = 0;
unsigned getname = 1;
int result = 0;
unsigned use128k = 0;
unsigned startaddr =0;
char* infile = NULL;
const char* outfile = NULL;
memset(&snapshot, 0, sizeof(snapshot));
try
{
if (argc < 2)
{
printf( "Convert .a01 -> sna\n"
"Usage:\n"
"%s [options] inputfile\n\n"
"Options:\n"
"-o <filename> -- specify output file name (else it will be taken from dump or input filename)\n"
"-v -- be verbose\n"
"-bN -- set border to N\n"
"-rN -- set run address to N\n"
, *argv);
throw 1;
}
int argind = 1;
for (;;)
{
if (argind == argc)
throw "Wrong parameters";
if (argind == argc - 1)
{
infile = argv[argind];
break;
}
if (! strcmp(argv[argind], "-v"))
{
verbose = 1;
argind++;
} else
if (! strcmp(argv[argind], "-o"))
{
outfile = argv[argind + 1];
argind += 2;
} else
if (! strncmp(argv[argind], "-b", 2))
{
snapshot.hdr1.border = atoi(argv[argind++] + 2) & 7;
} else
if (! strncmp(argv[argind], "-r", 2))
{
startaddr = atoi(argv[argind++] + 2);
}
}
char outname[256] = {0};
{
FdEnv file(fopen(infile, "rt"));
char instr[520];
BYTE dump[256];
//prepare filename
if (outfile)
strncpy(outname, outfile, 256);
else
strncpy(outname, infile, 256);
while (fgets(instr, 520, file))
{
unsigned mode = 0;
unsigned count = 0;
if (sscanf(instr, "S%1i%02x", &mode, &count) != 2) throw "Wrong file!";
infile = instr + 4;
BYTE* out = dump;
unsigned crc = count;
unsigned cnt = 0;
while (sscanf(infile, "%02x", dump + cnt) && cnt != count)
{
crc += dump[cnt++];
infile += 2;
}
if (count != cnt) throw "Error in file!";
if (0xff != (crc & 0xff)) throw "Wrong crc!";
unsigned addr = (dump[0] << 24) | (dump[1] << 16) | (dump[2] << 8) | dump[3];
out = dump + 4;
switch (mode)
{
case 0:
if (! outfile)
{
memcpy(outname, dump + 2, cnt - 3);
outname[cnt - 3] = 0;
}
break;
case 1:
out--;
addr >>= 8;
case 2:
out--;
addr >>= 8;
case 3:
if (addr & 0xffff0000) throw ">16 bit addresses are not supported";
while (out != dump + cnt - 1)
{
if (addr >= 0x4000 && addr < 0xffff)
snapshot.hdr1.memory[addr - 0x4000] = *out;
out++;
addr++;
}
break;
case 5:
break;
case 9:
out--;
addr >>= 8;
case 8:
out--;
addr >>= 8;
case 7:
if (!startaddr) startaddr = addr;
break;
default:
throw "Unknown field type!";
}
}
if (startaddr & 0xffff0000) throw "> 16 bit start address is not supported";
if (verbose)
{
printf("Created %s\nPC=%#x\n", outname, startaddr);
}
if (use128k)
snapshot.pc = startaddr;
else
{
snapshot.hdr1.sp = 0x4000;
snapshot.hdr1.memory[0] = startaddr & 0xff;
snapshot.hdr1.memory[1] = startaddr >> 8;
}
}
infile = strrchr(outname, '.');
if (! infile) infile = strrchr(outname, 0);
strcpy(infile, ".sna");
FdEnv file(fopen(outname, "wb"));
fwrite(&snapshot, use128k ? sizeof(SNA128) : sizeof(SNA48), 1, file);
}
catch (const char* msg)
{
puts(msg);
result = 1;
}
catch (int val)
{
result = val;
}
catch (...)
{
puts("Unknown exception");
result = 1;
}
return result;
}