diff --git a/doc/grc.txt b/doc/grc.txt index 53d307a1f..25ccfd845 100644 --- a/doc/grc.txt +++ b/doc/grc.txt @@ -7,7 +7,7 @@ VII 2000 - VI 2002 + VI,VII 2002 @@ -33,6 +33,9 @@ file. Assembler source should be processed with ca65 and linked as first object (read Building process below). VLIR structure is currently supported only for project written entirely in assembler. +grc can be also used as a handy VLIR linker used to build VLIR-structured .cvt +file out of prepared binary chains. + 2. Usage -------- @@ -43,6 +46,9 @@ grc accepts following options: -l name name ld65 output file -h help +when used as VLIR linker the correct syntax is: + grc -vlir output.cvt header.bin vlir0.bin vlir1.bin... + Default output names are made from input name with extension replaced by '.h' and '.s'. grc will not overwrite existing files unless forced to do so. This is to avoid situation where you have test.c and test.grc files. Both would @@ -149,8 +155,8 @@ denotes empty chains. In this example chains #1 and #3 are missing. The names between brackets are names of binaries containing code for each VLIR part. They matter only for generated ld65 configuration file and will be the names of resulting binary files after linking. Each one will contain one VLIR -chain and they will have to be put together into VLIR .cvt by vlink utility in -correct order. +chain and they will have to be put together into VLIR .cvt by grc in VLIR linker +modey in correct order. The 'headname' will be the name for binary which will contain only GEOS .cvt header made out of compiling .s header file generated also by grc. At the end of resulting ld65 config file (.cfg) in comments there will be @@ -291,7 +297,7 @@ The last step is to put them together in the right order, order of arguments is important this time. As suggested in comments at the end of cvthead.cfg we do: -$ vlink output.cvt vlir-head.bin vlir-0.bin vlir-1.bin vlir-2.bin +$ grc -vlir output.cvt vlir-head.bin vlir-0.bin vlir-1.bin vlir-2.bin This is the end. The file 'output.cvt' can be unconverted under GEOS. Note that the switch '-t geos' wasn't present at any stage of this process. diff --git a/src/grc/grc.c b/src/grc/grc.c index 4fac3895b..b71efc4fb 100644 --- a/src/grc/grc.c +++ b/src/grc/grc.c @@ -43,6 +43,91 @@ void Error (const char* Format, ...) exit (EXIT_FAILURE); } + +void VLIRLinker(int argc, char *argv[]) { +FILE *outCVT, *input; +unsigned char buffer[BLOODY_BIG_BUFFER]; +unsigned char vlirtabt[127]; +unsigned char vlirtabs[127]; +int i,j; +size_t bytes; +int blocks,rest; + + i=2; + + /* check if we know enough */ + + if (argc<4) + Error("too less arguments, required [out] [cvthead] [vlir0] ...\n"); + + /* first open and copy CVT header */ + + outCVT = fopen(argv[i],"wb+"); + if (outCVT==NULL) + Error("can't open output\n"); + + ++i; + input = fopen(argv[i],"rb"); + if (input==NULL) + Error("can't open input:%s\n",strerror(errno)); + + bytes = fread(buffer,1,BLOODY_BIG_BUFFER,input); + fclose(input); + if (bytes!=508) + Error("%s is not a cvt header\n",argv[i]); + + fwrite(buffer,1,bytes,outCVT); + + /* now put 254 bytes of VLIR table, to update later */ + + /* clear out things */ + memset(buffer,0,254); + fwrite(buffer,1,254,outCVT); + for (j=0;j!=126;j++) { + vlirtabt[j]=0; + vlirtabs[j]=0; + } + + /* now read all VLIR chains, aligned to 254 bytes */ + + ++i; + j=0; + while (i!=argc) { + if (strcmp(argv[i],"blank")==0) { + vlirtabt[j]=0; vlirtabs[j]=0; } + else if (strcmp(argv[i],"noexist")==0) { + vlirtabt[j]=0; vlirtabs[j]=0xff; } + else { + memset(buffer,0,BLOODY_BIG_BUFFER); + input = fopen(argv[i],"rb"); + if (input==NULL) + Error("couldn't open %s:%s\n",argv[i],strerror(errno)); + bytes = fread(buffer,1,BLOODY_BIG_BUFFER,input); + fclose(input); + if (bytes<0) + Error("couldn't read %s:%s\n",argv[i],strerror(errno)); + blocks = bytes / 254; + rest = bytes % 254 + 2; + if (rest>255) rest=255; + vlirtabt[j]=blocks+1; vlirtabs[j]=rest; + fwrite(buffer,1,(blocks+1)*254,outCVT); + } + ++j; + ++i; + } + + /* now rewind and update VLIR table */ + + fflush(outCVT); + fseek(outCVT,508,SEEK_SET); + for (i=0;i!=127;i++) { + fputc(vlirtabt[i],outCVT); + fputc(vlirtabs[i],outCVT); + } + fclose(outCVT); + exit(EXIT_SUCCESS); +} + void printCHeader (void) { fprintf(outputCFile, "\n/*\n\tThis file was generated by GEOS Resource Compiler\n" @@ -64,7 +149,7 @@ void printVHeader (void) { "\n#\tDO NOT EDIT! Any changes will be lost!\n#" "\n#\tEdit proper resource file instead\n#" "\n#\tLook at end of this file to find commandline that must be used\n" - "#\tto invoke ld65 and vlink\n#" + "#\tto invoke ld65 and grc (as VLIR linker)\n#" "\n#\n\n"); } @@ -108,8 +193,9 @@ void printUsage (void) { "\t-f\t\tforce writting files\n" "\t-o name\t\tname C output file\n" "\t-s name\t\tname asm output file\n" - "\t-l name\t\tname ld65 config output file (for vlir)\n", - progName); + "\t-l name\t\tname ld65 config output file (for vlir)\n" + "Or as VLIR linker: %s -vlir output.cvt header [vlir0] ... [blank] ... [vlir_n]\n", + progName,progName); } @@ -491,7 +577,7 @@ struct vlirentry vlirtable[127]; /* now put usage info */ fprintf(outputVFile,"\n# ld65 -o output.cvt -C %s file1.o file2.o ...",outputVName); - fprintf(outputVFile,"\n# vlink outputname %s",headname); + fprintf(outputVFile,"\n# grc -vlir outputname %s",headname); for (i=1;i<=numchains;i++) { fprintf(outputVFile," %s",vlirtable[i].chainname); } @@ -601,6 +687,15 @@ char *p, *tmp; printUsage(); exit (EXIT_SUCCESS); break; + case 'v': + if (strcmp(arg,"-vlir")==0) { + VLIRLinker(argc,argv); + exit (EXIT_SUCCESS); + break; + } else { + Error("unknown option %s\n",arg); + break; + } default: Error("unknown option %s\n",arg); } } else {