STOS MBK MAKER
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)