home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
-
- /* SET TABS TO 4 !!!! */
-
- /* ST2Amiga Format-convert ST Executables to Amiga Executables.
- *
- * (C) Copyright, Dave Campbell 90/91
- *
- * This software is freely distributable. Modified versions may be
- * redistributed provided that the modifications made are fully
- * documented as such.
- *
- * Its purpose is to aid the binary conversion of ST executables into
- * Amiga executables using the ReSource disassembler. To do this
- * you'll need some good books such as "Advanced MSDOS Programming" by
- * Ray Duncan, and other books on GEM (books on PC-GEM are best).
- * The ST's system call TRAPs map directly to PC and GEM calls. Eg
- * TRAP #1 is INT 21h.
- *
- * Don't forget to send me whatever you've converted (PD only)!!
- *
- * Many ST programs use very large BSS sections making them particularly
- * memory-hungry. The ST's memory allocation scheme is totally stuffed
- * and so many programs do their own memory allocation from their huge
- * BSS section. The people who designed the ST's OS certainly made
- * many more mistakes than Commodore did with the Amiga.
- *
- * There is a program called Dos-2-Dos which provides copying of files
- * to/from ST format disks.
- * Older ST disks are the same format as MSDOS 720k 3.5 inch, but the
- * bootblock and possibly a few other small things are slightly different.
- * All newer standard ST formatted disks will be identical to MSDOS
- * formatted disks.
- *
- * The ST does not support scatter-loading. All sections must be
- * consecutive; CODE, DATA, BSS. For this reason I merge the code
- * and data sections, and besides, it makes the job easy for me.
- * BSS comes out as a separate hunk -> its your responsibility to fix
- * up the dependencies.
- *
- * Why don't I space my source out more? I feel sorry for my space bar.
- *
- * Contact address:
- *
- * David Campbell
- * 36 Hemsworth Street
- * Acacia Ridge QLD 4110
- * AUSTRALIA
- *
- * email: dave@csis.dit.csiro.au
- *
- * If you haven't heard of ReSource, its the ultimate disassembler.
- * For ReSource contact:
- *
- * In OZ: Glen McDiarmid In the US: The Puzzle Factory
- * 28 Marginson Street PO Box 986
- * Ipswich QLD 4305 Veneta OR 97487
- * AUSTRALIA USA
- *
- * (07) 812-2963 (503) 935 3709
- */
-
- struct st_header {
- unsigned short branch;
- unsigned long code_size;
- unsigned long data_size;
- unsigned long bss_size;
- unsigned long sym_size;
- unsigned long xx;
- unsigned long flag0;
- unsigned short xxxx;
- };
-
- struct symbol {
- unsigned long sym_name;
- unsigned long sym_name2; /* 8 character symbols */
- unsigned short flags;
- unsigned long offset;
- };
-
- main(argc,argv)
- int argc;
- char **argv;
- {
- struct st_header ah;
- unsigned long codedata_size,bss_size; /* in longwords, not bytes */
- unsigned long first_long,count;
- unsigned char b;
- long apos;
- int r;
- unsigned long l,num_hunks;
- FILE *inf,*outf;
- char *mem;
- if(argc!=3) {
- usage:
- printf( "\2335;33mST2Amiga\2330;31m 1.1"
- " Format-convert executables from ST -> Amiga.\n"
- " For use with the ReSource disassembler.\n"
- " by Dave Campbell (dave@csis.dit.csiro.au)."
- "\n\n\2335;33mUSAGE: ST2Amiga <ST-Exe> <Amiga-Exe>"
- "\2330;31m\n\n");
- exit(0);
- }
- inf=fopen(argv[1],"r");
- if(!inf) {
- printf("Error reading file %s.\n",argv[1]);
- exit(0);
- }
- outf=fopen(argv[2],"w");
- if(!outf) {
- printf("Error writing file %s.\n",argv[2]);
- exit(0);
- }
- r=fread((char *)&ah,1,sizeof(ah),inf);
- if(r!=sizeof(ah)) {
- inv_atari_exe:
- printf("Invalid atari executable %s.\n",argv[1]);
- exit(0);
- }
- if(ah.branch!=0x601a)
- goto inv_atari_exe; /* anti-goto people go jump */
-
- printf("Code size: $%lx\n",ah.code_size);
- printf("Data size: $%lx\n",ah.data_size);
- printf("Bss size: $%lx\n",ah.bss_size);
- if(!(ah.flag0&1))
- printf("Warning: This Atari executable assumes a cleared heap.\n");
-
- codedata_size=(ah.code_size+ah.data_size+3)>>2; /* up to next longword */
- bss_size=(ah.bss_size+3)>>2;
-
- l=0x03f3; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_header */
- l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* end of name list */
- num_hunks=0;
- if(codedata_size) ++num_hunks;
- if(bss_size) ++num_hunks;
- fwrite((char *)&num_hunks,sizeof(long),1,outf); /* table size */
- l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* first hunk */
- --num_hunks;
- fwrite((char *)&num_hunks,sizeof(long),1,outf); /* last hunk */
- ++num_hunks;
- if(codedata_size) /* size of each hunk */
- fwrite((char *)&codedata_size,sizeof(long),1,outf);
- if(bss_size)
- fwrite((char *)&bss_size,sizeof(long),1,outf);
- if(codedata_size) {
- l=0x03e9; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_code */
- fwrite((char *)&codedata_size,sizeof(long),1,outf);
- mem=(char *)malloc(codedata_size<<2);
- if(!mem) {
- printf("Cannot allocate %d bytes of memory.\n",codedata_size<<2);
- exit(0);
- }
- r=fread(mem,1,ah.code_size+ah.data_size,inf);
- if(r!=ah.code_size+ah.data_size) {
- free(mem);
- goto inv_atari_exe;
- }
- fwrite(mem,1,codedata_size<<2,outf);
- free(mem);
- }
- if(ah.sym_size) { /* symbols are present */
- struct symbol sym;
- int hunk_written=0;
- count=ah.sym_size/sizeof(sym);
- while(count) {
- r=fread((char *)&sym,1,sizeof(sym),inf);
- if(r!=sizeof(sym))
- goto inv_atari_exe;
- if(!(sym.flags&0x4000)) {
- if(!hunk_written) {
- l=0x03f0; fwrite((char *)&l,sizeof(long),1,outf);
- /* hunk_symbol */
- hunk_written=1; /* never again */
- }
- l=0x0002; fwrite((char *)&l,sizeof(long),1,outf);
- /* length of symbols in longs */
- /* printf("%04x %s\n",sym.flags,
- (sym.flags=0,(char *)&sym.sym_name)); */
- fwrite((char *)&sym.sym_name,1,8,outf);
- fwrite((char *)&sym.offset,sizeof(long),1,outf);
- }
- count--;
- }
- l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* terminator */
- }
- r=fread((char *)&first_long,1,sizeof(long),inf); /* read first reloc long */
- if(r!=sizeof(long))
- goto inv_atari_exe;
- if(first_long) {
- count=1;
- l=0x03ec; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_reloc32 */
-
- apos=ftell(inf);
- r=fread((char *)&b,1,1,inf); /* first pass to count */
- if(r!=1)
- goto inv_atari_exe;
- while(b) {
- if(b>=2 && b<255) /* only count the relocs */
- ++count;
- fread((char *)&b,1,1,inf);
- }
- fwrite((char *)&count,1,sizeof(long),outf);
- l=0; fwrite((char *)&l,sizeof(long),1,outf); /* reloc on hunk 0 */
- fwrite((char *)&first_long,1,sizeof(long),outf);
- fseek(inf,apos,0); /* back to where we were */
- r=fread((char *)&b,1,1,inf);
- if(r!=1)
- goto inv_atari_exe;
-
- /* ST relocation scheme */
-
- while(b) { /* 0 -> end of relocation */
- if(b==1)
- first_long+=254; /* 1 -> skip 254 bytes */
- else if(b&1)
- goto inv_atari_exe; /* other odds undefined */
- else { /* other evens skip bytes and relocate */
- first_long+=b;
- fwrite((char *)&first_long,sizeof(long),1,outf);
- }
- r=fread((char *)&b,1,1,inf);
- if(r!=1)
- goto inv_atari_exe;
- }
- l=0x0000; fwrite((char *)&l,sizeof(long),1,outf); /* end of reloc */
- l=0x03f2; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_end */
- }
- if(bss_size) {
- l=0x03eb; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_bss */
- fwrite((char *)&bss_size,sizeof(long),1,outf);
- fseek(inf,ah.bss_size,1);
- }
- l=0x03f2; fwrite((char *)&l,sizeof(long),1,outf); /* hunk_end */
-
- /* CLOSE UP SHOP */
-
- fclose(inf);
- fclose(outf);
- }
-