STOS MBK MAKER

From Atari Wiki
Revision as of 21:12, 10 July 2007 by Nyh (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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
  • /
  1. include <stdlib.h>
  2. include <stdio.h>
  3. include <string.h>


  1. define FILE_NAAM8_3 /* undef for unrestricted filenames */
  1. define PRINT_INFO /* show processing status */
  1. define ATARI_MEMLIMIT (4L*1024L*1024L)
  2. define MAX_PATH 256 /* maximum path size for file */
  1. define MBS_HEADER_SIZE 78
  2. define MBK_HEADER_SIZE 18
  3. define BAS_HEADER_SIZE 78
  4. 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) {

  1. 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;
 }
  1. else
 (void)naam;
  1. 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) {

  1. 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--;
 }
  1. else
 (void)naam;
  1. 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)