/* v1.01
BIN2OBJ Binary to OBJ file converter by Adam Seychell, May 1995.
How to compile with Borland C v4.0+;
You will need BCC32.EXE, DLINK.EXE, PAL.LIB, and PAL.H
BCC32 -c -B BIN2OBJ.c
DLINK -c BIN2OBJ ,,, pal.lib
*/
#include <stdio.h>
int i,t,data_length,wr_ptr,p,data_offset;
FILE *source_file;
FILE *dest_file;
unsigned char c;
char * source_name;
char * dest_name;
char * public_symbol;
int LEDATA_buffersize;
unsigned char * LEDATA_buffer;
unsigned char * LEDATA_buffer_old;
unsigned char LNAMES_SEGDEF_record[28]={
/* names record */
0x96,0x0D,0x00,
0x00,0x05,0x5F,0x54,0x45,0x58,0x54,0x04,0x43,0x4F,0x44,0x45,0x95,
/* segment definistion record */
0x99,0x09,0x00,
0xA9,0xA0,0x86,0x01,0x00,0x02,0x03,0x01,0x88
};
unsigned char MODEND_record[12]={
0x88,0x04,0x00,0x00,0xA2,0x01,0xD1,
0x8A,0x02,0x00,0x00,0x74
};
void exit_wr_error(void)
{
fprintf(stderr,"Error creating output file '%s' \n",dest_name);
exit(1);
}
char getkey(void)
{
int i;
asm {
mov ah,0
int 16h
movzx eax,al
mov i,eax
}
return i;
}
unsigned char calc_Checksum(unsigned char * string, int length )
{
unsigned char i;
asm mov edx,string
asm mov ecx,length
asm mov al,0
loooper:
asm sub ecx,1
asm jl exitt
asm add al,[edx+ecx]
asm sub ecx,1
asm jl exitt
asm add al,[edx+ecx]
asm sub ecx,1
asm jl exitt
asm add al,[edx+ecx]
asm sub ecx,1
asm jl exitt
asm add al,[edx+ecx]
asm sub ecx,1
asm jl exitt
asm add al,[edx+ecx]
asm jmp loooper
exitt:
asm mov i,al
return (i);
}
void write_byte(unsigned char value)
{
if( fputc(value, dest_file) == EOF)
exit_wr_error();
}
void write_word(unsigned short value)
{
fputc( *( (char *)&value + 0) ,dest_file);
fputc( *( (char *)&value + 1) ,dest_file);
}
void write_dword(unsigned value)
{
fputc( *( (char *)&value + 0) ,dest_file);
fputc( *( (char *)&value + 1) ,dest_file);
fputc( *( (char *)&value + 2) ,dest_file);
fputc( *( (char *)&value + 3) ,dest_file);
}
void write_it(void * value, int count)
{
if( fwrite(value, 1, count, dest_file) != count)
exit_wr_error();
}
FILE * openfile(char * name ,char * type)
{
FILE * i;
i=fopen(name,type);
if (i == NULL ) {
printf("Cannot to open the file '%s'",name);
exit(1);
}
return (i);
}
char * Add_ext(char * string, char * exten)
{
int i,t;
char c;
i = strlen(string);
for (t=0; t < i ; t++) {
c = *(string+i-t-1);
if ( (c == '.') || (c == '\\') )
break;
}
if (c != '.') {
string=memcpy(malloc(i+5),string,i);
strcpy(string+i,exten);
}
return(string);
}
int main( int argc, char *argv[] )
{
printf("BIN to OBJ Converter Version 1.02 by Adam Seychell. 20/Nov/1995\n\n");
if ( argc != 4 )
{
printf(
"BIN2OBJ is a utility for creating an object module (OBJ file) containing the\n"
"binaray data from a specified file. A public symbol is defined in the object\n"
"module which will refrence the beginning of the data. This program allows\n"
"large amounts of data to be easily linked into the executable.\n");
printf(
"\n"
"Usage: bin2obj <source> <destination[.OBJ]> <public name>\n"
"\n"
"Examples: bin2obj song.s3m song IntroSong\n"
" bin2obj anim0001.pcx anim0001 Animation_0001\n"
" bin2obj xfile xfile _Xdata\n\n");
return EXIT_FAILURE;
}
source_name= argv[1];
dest_name= Add_ext(argv[2],".OBJ");
public_symbol=argv[3];
LEDATA_buffersize = maxavail();
if (LEDATA_buffersize > 0x20000) LEDATA_buffersize = 0x20000;
if (LEDATA_buffersize < 4096) {
fprintf(stderr,"not enough memory\n");
exit(1);
}
LEDATA_buffer=malloc(LEDATA_buffersize+4);
source_file=openfile(source_name,"rb");
dest_file=openfile(dest_name,"wb");
fseek(source_file,0,SEEK_END);
data_length=ftell(source_file);
fseek(source_file,0,SEEK_SET);
/*******THEADER--Translator Header Record******************/
write_byte(0x80); /* record type */
i=strlen(source_name);
write_word(i+2); /* record length */
write_byte(i);
write_it(source_name,i);
/* Checksum */
write_byte(-(0x80+2+i+i+calc_Checksum(source_name,i)));
/******LNAMES--List of Names Record************/
/*******SEGDEF--Segment Definition Record (32bit)**********/
(unsigned int)*(unsigned int *)&LNAMES_SEGDEF_record[20] = data_length;
c = LNAMES_SEGDEF_record[20] + LNAMES_SEGDEF_record[21];
c += LNAMES_SEGDEF_record[22] + LNAMES_SEGDEF_record[23];
LNAMES_SEGDEF_record[27]=-(c+0x99+0x09+0xA9+0x02+0x03+0x01);
write_it(&LNAMES_SEGDEF_record,sizeof(LNAMES_SEGDEF_record));
/****** PUBDEF--Public Names Definition Record (32bit)**********/
i = strlen(public_symbol);
write_byte(0x90); /* record type */
write_word(7+i); /* record length */
write_byte(0x00); /* group index */
write_byte(0x01); /* segment index */
write_byte(i); /* string length */
write_it(public_symbol,i); /* public symbol */
write_word(0x0000); /* public offset */
write_byte(0x00); /* type index */
/* Checksum */
write_byte(-(0x90+7+i+0x01+i+calc_Checksum(public_symbol,i)));
/****** A1H LEDATA--LOGICAL ENUMERATED DATA RECORD **********/
data_offset=0;
LEDATA_buffer_old = LEDATA_buffer;
for (;;)
{
LEDATA_buffer = LEDATA_buffer_old;
for (; (LEDATA_buffer-LEDATA_buffer_old) < (LEDATA_buffersize-1040) ;)
{
i=fread( LEDATA_buffer+8, 1 , 1024, source_file );
if ( i == 0 ) break;
if ( i == EOF ) {
fprintf(stderr,"Error reading source file '%s'\n",source_name);
exit(1);
}
/** fixup the LEDATA length & data offset & checksum **/
*(LEDATA_buffer+0)=0xA1;
*(LEDATA_buffer+3)=0x01;
(short)*(short *)(LEDATA_buffer+1) = i + 6;
(long)*(long *)(LEDATA_buffer+4) =data_offset;
*(LEDATA_buffer+i+8)= -calc_Checksum(LEDATA_buffer,i+8);
data_offset+=i;
LEDATA_buffer += i+9;
}
write_it(LEDATA_buffer_old, LEDATA_buffer-LEDATA_buffer_old );
if ((i == 0) || (ctrl_break_count != 0) ) break;
}
/******* 8AH MODEND--MODULE END RECORD *******/
write_it(&MODEND_record,sizeof(MODEND_record));
printf("%d bytes converted.\n",data_offset);
fclose(source_file);
fclose(dest_file);
return 0;
}