/*
To work the first commented out byte (a counter) of each register must be uncommented.
The counter to how many different bytes are used within the "SHANNON'-coding...
*/
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#define PHRASES MAX 100
#define MAX PHRASE LEN 100
struct phrase
{
int phrase[MAX PHRASE LEN];
int len;
int count;
};
phrase phrases[PHRASES MAX];
const MAXBUFF = 2000000;
//START inclusive
#define ENCODE START 0
//END exclusive
#define ENCODE END 11
FILE *inFile;
FILE *outFile;
FILE *outFile2;
unsigned char buf[MAXBUFF];
unsigned char out buf[MAXBUFF/11+11][11];
int len;
int vbl len;
int byte pointer read = 0;
int byte pointer write = 0;
int current bit counter = -1;
int current out byte=0;
#define MAP BIT MAX 127
#define MAP CODE MAX 255
int map[MAP BIT MAX][MAP CODE MAX];
int GET BYTE()
{
current bit counter = -1;
return buf[byte pointer read++];
}
void WRITE BYTE(int byte)
{
fprintf(outFile," DB $%02X \n",byte);
fwrite(&byte,1,1,outFile2);
}
int GET BIT()
{
if (current bit counter == -1)
{
current out byte = GET BYTE();
current bit counter = 7;
}
if (current out byte&(1<<(current bit counter--)))
{
return 1;
}
return 0;
}
int total unpack count = 0;
int main( int argc, char* argv[] )
{
cout " nCalling ";
for (int ii=0;ii<argc;ii++)
cout " "argv[ii];
cout " \n \n";
if ( argc != 2 )
{
cout "Usage: decode <infile> \n";
return 0;
}
inFile=fopen(argv[1],"rb");
if( !inFile )
{
cout "A file error occured with " argv[1] "! \n";
return 2;
}
len=fread( buf, sizeof(char),sizeof(char)*MAXBUFF,inFile );
fclose(inFile);
printf("Length of file: %i \n",len);
vbl len = GET BYTE()*256+GET BYTE();
printf("Length of track: %i \n",vbl len);
int ym register;
outFile=fopen("out int.asm","wb+");
if (!outFile)
{
printf("File Open Error! \n");
return 1;
}
outFile2=fopen("out int.bin","wb+");
if (!outFile2)
{
printf("File Open Error! \n");
return 1;
}
fprintf(outFile," DW %i ; length of track \n", vbl len);
for (ym register=ENCODE START; ym register< ENCODE END; ym register++)
{
int to map = GET BYTE();
int i;
printf("Register %i has %i different "bytes' \n", ym register, to map);
// initialize mapper
fprintf(outFile,"; mapper for ym register %i \n", ym register);
fprintf(outFile," DB $%02X ; uses different bytes \n", to map);
for (i=0; i < MAP BIT MAX; i++)
{
for (int j=0; j < MAP CODE MAX; j++)
{
map[i][j] = -1;
}
}
int no phrases=0;
for (i=0; i < to map; i++)
{
int bits = GET BYTE();
int code = GET BYTE();
int real byte = GET BYTE();
fprintf(outFile," DB %02X, %02X, %02X ; bits, code, realbyte \n", bits, code, real byte);
if ((bits&127) > MAP BIT MAX)
{
printf("Bit overflow - bye! \n");
exit(1);
}
map[bits&127][code] = real byte;
if (bits&128)
{
no phrases++;
map[bits&127][code]+=256;
}
}
fprintf(outFile,"; Phrases follow (%i) \n",no phrases);
// load phrases
for (i=0;i<no phrases;i++)
{
phrases[i].len = GET BYTE();
fprintf(outFile," DB %02X", phrases[i].len);
int j;
for (j=0;j < phrases[i].len; j++)
{
phrases[i].phrase[j] = GET BYTE();
fprintf(outFile,", %02X", phrases[i].phrase[j]);
}
fprintf(outFile," \n");
}
fprintf(outFile,"; Data follows...\n");
// done... now start decoding!
int byte decrunched count = 0;
while (byte decrunched count < vbl len)
{
int RLE count = 0;
if (GET BIT() == 0)
{
// one byte
RLE count = 1;
}
else
{
// rle encoded
int count bits = 1; // already got a 1, see above
while (GET BIT() == 1)
{
count bits++;
}
count bits+=2; // plus two, since we start coding with 3 bits
// the following count bits represent the RLE count
// lsb first
for (i=0; i < count bits; i++)
{
RLE count+= i);
}
}
// in RLE count now the number of times we should repeat the
// following bit data...
// msb first
int bits = 0;
int code = 0;
int is phrase = 0;
int unpacked byte = 0;
while (1)
{
code = 1;
code += GET BIT();
bits++;
if (map[bits][code] != -1)
{
unpacked byte = map[bits][code];
if (unpacked byte>=256)
{
is phrase = 1;
unpacked byte -= 256;
}
break;
}
}
/*
fprintf(outFile,"; byte decrunched count %i \n",byte decrunched count);
if (is phrase == 0)
fprintf(outFile,"; byte %02X, times %i \n",unpacked byte,RLE count);
else
fprintf(outFile,"; phrase %02X, times %i \n",unpacked byte,RLE count);
*/
for (i=0; i<RLE count; i++)
{
if (is phrase == 0)
{
WRITE BYTE(unpacked byte);
byte decrunched count++;
total unpack count++;
}
else
{
int j;
for (j=0;j<phrases[unpacked byte].len;j++)
{
WRITE BYTE(phrases[unpacked byte].phrase[j]);
byte decrunched count++;
total unpack count++;
}
}
}
}
}
printf("Bytes unpacked: %i \n", total unpack count);
fclose(outFile);
fclose(outFile2);
return 0;
}