STOS MBK MAKER
Jump to navigation
Jump to search
This is the C source of a program for extracting STOS memorybanks and storing them as .MBK files from .BAS, .PRG, .MBS files. Compile it into a TTP and enter as arguments any fie you want to extract STOS memory banks from.
/*
- mbk creator
- read a file and try to extract STOS memory blocks from it
- make_mbk is a small utility to extra STOS memory banks,
- (.MBK files) from data or program files. Just drop a
- file on make_mbk.ttp and the program will analyze the
- file and extract STOS memorybanks from the file when
- any found. Note a lot of STOS demo's don't have the
- .PRG extension. The program doesn't care and will
- extract the memory banks anyway. Be aware a lot of STOS
- programs are packed with program packers like Atomik or
- Ice. You have to depack such programs first with a
- tool like Synergy depack or Multi depack.
- Placed in public domain, july 2007 Hans Wessels
- /
- include <stdlib.h>
- include <stdio.h>
- include <string.h>
- define FILE_NAAM8_3 /* undef for unrestricted filenames */
- define PRINT_INFO /* show processing status */
- define ATARI_MEMLIMIT (4L*1024L*1024L)
- define MAX_PATH 256 /* maximum path size for file */
- define MBS_HEADER_SIZE 78
- define MBK_HEADER_SIZE 18
- define BAS_HEADER_SIZE 78
- define PRG_HEADER_SIZE 106
unsigned long get_long(const unsigned char *p) {
unsigned long res; res=*p++; res<<=8; res+=*p++; res<<=8; res+=*p++; res<<=8; res+=*p; return res;
}
unsigned int get_word(const unsigned char *p) {
unsigned int res; res=*p++; res<<=8; res+=*p; return res;
}
void put_long(unsigned char* p, unsigned long data)
{
p[3]=(unsigned char)(data&0xff); data>>=8; p[2]=(unsigned char)(data&0xff); data>>=8; p[1]=(unsigned char)(data&0xff); data>>=8; p[0]=(unsigned char)(data&0xff);
}
void make_filenaam(char* naam) {
- ifdef FILE_NAAM8_3
int len=(int)strlen(naam);
int naam_start=len;
int i;
if(naam_start==0)
{
return;
}
while((naam_start!=0) && (naam[naam_start-1]!='\\'))
{ /* zoek einde van het path en begin van de file naam */
naam_start--;
}
i=len;
while(i>=naam_start)
{
if(naam[i]=='.')
{
naam[i]=0;
}
i--;
}
len=(int)strlen(naam);
if((len-naam_start)>7)
{
naam[naam_start+7]=0;
}
- else
(void)naam;
- endif
}
void read_banks(char* naam, FILE* f, long size, long data, long bank_info) {
unsigned char* file;
unsigned char header[18]="Lionpoubnk"; /* we will patch in bank no and size later */
if(size>ATARI_MEMLIMIT)
{
return;
}
file=malloc(size);
if(file==NULL)
{
printf("Out of memory.\n");
return;
}
fseek(f, 0, SEEK_SET);
fread(file, 1, size, f);
{
long i;
char base_path[MAX_PATH];
sprintf(base_path, naam);
make_filenaam(base_path);
for(i=0;i<15;i++)
{
long len;
len=get_long(file+bank_info+4*i);
if(len!=0)
{ /* memory bank gevonden */
put_long(header+10, i+1);
put_long(header+14, len);
len=len&(0xffffffL); /* strip banktype */
if((data+len)<=size)
{ /* within limits */
FILE* dst;
char path[MAX_PATH];
sprintf(path, "%s%lx.mbk", base_path, i);
#ifdef PRINT_INFO
printf("output: %s\n", path);
#endif
dst=fopen(path, "wb");
if(dst!=NULL)
{
fwrite(header, 1, 18, dst);
fwrite(file+data, 1, len, dst);
fclose(dst);
}
}
data+=len;
}
}
}
free(file);
}
void make_ext(char* naam) {
- ifdef FILE_NAAM8_3
int len=(int)strlen(naam);
int naam_start=len;
int i;
if(naam_start==0)
{
return;
}
while((naam_start!=0) && (naam[naam_start-1]!='\\'))
{ /* zoek einde van het path en begin van de file naam */
naam_start--;
}
i=len;
while(i>=naam_start)
{
if(naam[i]=='.')
{
naam[i]=0;
}
i--;
}
- else
(void)naam;
- endif
}
void write_mbk(char* naam, FILE* f, long size)
{
unsigned char* file;
if(size>ATARI_MEMLIMIT)
{
return;
}
file=malloc(size);
if(file==NULL)
{
printf("Out of memory.\n");
return;
}
fseek(f, 0, SEEK_SET);
fread(file, 1, size, f);
{
char path[MAX_PATH];
FILE* dst;
sprintf(path, naam);
make_ext(path);
sprintf(path, "%s.mbk", path);
#ifdef PRINT_INFO
printf("output: %s\n", path);
#endif
dst=fopen(path, "wb");
if(dst!=NULL)
{
fwrite(file, 1, size, dst);
fclose(dst);
}
}
free(file);
}
void read_mbk(char * naam)
{
unsigned char *file;
FILE* f;
long int len;
file=malloc(2048);
if(file==NULL)
{
printf("Out of memory.");
return;
}
f=fopen(naam, "rb");
if(f==NULL)
{
printf("Can not open file!");
}
else
{
len=fread(file, 1, 256, f);
if(len!=256)
{
printf("File too small: %li", len);
}
if((strncmp("Lionpoubnk", file, 10)==0) && (get_long(file+10)==0))
{ /* STOS MBS */
long size;
long start_data;
long bank_info;
size=get_long(file+14)+MBS_HEADER_SIZE;
start_data=MBS_HEADER_SIZE;
bank_info=18;
read_banks(naam, f, size, start_data, bank_info);
}
else if((strncmp("Lionpoubnk", file, 10)==0) && (get_long(file+10)<16))
{ /* STOS MBK with wrong extension? save as mbk */
long size;
size=(get_long(file+14)&0xffffffL)+MBK_HEADER_SIZE;
write_mbk(naam, f, size);
}
else if(strncmp("Lionpoulos", file, 10)==0)
{ /* STOS BAS */
long size;
long start_data;
long bank_info;
size=get_long(file+10)+BAS_HEADER_SIZE;
start_data=get_long(file+14)+BAS_HEADER_SIZE;
bank_info=18;
read_banks(naam, f, size, start_data, bank_info);
}
else if((get_word(file)==0x601a) && ((get_long(file+112)==0x53746f73L) || (get_long(file+112)==0x53544f53L)))
{ /* STOS program, allowing for Stos and STOS header */
long size;
long start_data;
long bank_info;
size=get_long(file+30)+PRG_HEADER_SIZE;
start_data=get_long(file+34)+98;
bank_info=38;
read_banks(naam, f, size, start_data, bank_info);
}
fclose(f);
}
free(file);
}
int main(int argc, const char *argv[])
{
while(--argc>0)
{
#ifdef PRINT_INFO
printf("Processing: %s :\n", (char *)argv[argc]);
#endif
#ifdef PRINT_INFO
read_mbk((char *)argv[argc]);
#endif
}
return 0;
}
--Nyh 16:12, 10 July 2007 (EDT)