home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / language / f68k / loader.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-23  |  10.7 KB  |  374 lines

  1. /********************************************************************
  2.  
  3.     Loader program for a F68K image file
  4.     
  5.     
  6.     This loader tries to open a file F68K.CFG which
  7.     holds information about the F68K system to be loaded.
  8.     
  9.     
  10. ********************************************************************/
  11. #define DEBUG
  12.  
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <tos.h>
  17. #include <string.h> 
  18.  
  19.  
  20. #define CODESIZE 0x20000L
  21. #define DATASIZE 0x20000L
  22. #define TIBSIZE  2048
  23. #define MAX_DEVICES 10
  24. #define BPB  2048                 /* Bytes Per Block */
  25.  
  26. #define FALSE (0)
  27. #define TRUE (-1)
  28.  
  29. #define CONSOLE 2
  30.  
  31. #define fsize(x) Fseek(0L,fileno(x),2)
  32.  
  33.  
  34.  
  35. long cdecl key_quest();
  36. long cdecl key();
  37. void cdecl emit();
  38. long cdecl r_w();
  39. long cdecl writesys();
  40. long cdecl readsys();
  41.  
  42. void read_paras(long*);
  43. void read_segments(void**,void**);
  44.  
  45. char devicename[MAX_DEVICES][FILENAME_MAX];
  46. FILE* device[MAX_DEVICES];
  47. FILE* infile;
  48. long roottable[MAX_DEVICES*2 +1]; 
  49.  
  50. long codesz = CODESIZE;
  51. long datasz = DATASIZE; 
  52. char imagename[FILENAME_MAX] = "F68K.IMG";
  53. char outfilename[FILENAME_MAX] = "F68K.OUT";
  54. char cfgname[FILENAME_MAX] = "F68K.CFG";
  55.  
  56. void main(int argc, const char *argv[])
  57. {
  58. void *codeseg,*dataseg;
  59.  
  60.  
  61. long keytable[]        = {1, (long)key};
  62. long keyqtable[]    = {1, (long)key_quest};
  63. long emittable[]    = {1, (long)emit};
  64. long r_wtable[]        = {1, (long)r_w};
  65. long readsystable[]    = {1, (long)readsys};
  66. long writesystable[]    = {1, (long)writesys};
  67.  
  68. struct forthparas
  69. {
  70.     long registers[16];    /* to be filled by F68K */
  71.      void *data;        /* A3 */
  72.     void *code;        /* A5 */
  73.     void *datastack;    /* A6 */
  74.     void *retstack;      /* A7 */
  75.     void *TIBptr;
  76.     long codelen;
  77.     long datalen;
  78.     void *emittable;
  79.     void *keytable;
  80.     void *keyqtable;
  81.     void *r_wtable;
  82.     void *readsystable;
  83.     void *writesystable;
  84.     void *roottable;
  85. } forthparas; 
  86.  
  87. typedef void cdecl FUNC(struct forthparas*);
  88.  
  89.  
  90.     forthparas.emittable     = emittable;
  91.     forthparas.keytable     = keytable;
  92.     forthparas.keyqtable     = keyqtable;
  93.     forthparas.r_wtable     = r_wtable;
  94.     forthparas.readsystable = readsystable;
  95.     forthparas.writesystable= writesystable;
  96.     forthparas.roottable     = roottable;
  97.  
  98.  
  99.     if(argc==2)  strcpy(cfgname,argv[1]);
  100.  
  101.  
  102.         read_paras(roottable);
  103.         forthparas.codelen    = codesz;
  104.         forthparas.datalen    = datasz; 
  105.        
  106.         read_segments(&codeseg,&dataseg);
  107.         forthparas.code        = codeseg;
  108.         forthparas.data        = dataseg;
  109.         forthparas.datastack    = (void*)((long)dataseg+datasz-TIBSIZE);
  110.         forthparas.retstack    = (void*)((long)dataseg+datasz);
  111.         forthparas.TIBptr    = (void*)((long)dataseg+datasz-TIBSIZE);
  112.         
  113.         Super(0);
  114.         (*(FUNC*)codeseg)(&forthparas);
  115.  
  116. }
  117.  
  118.  
  119. /************************************************************************
  120. *                                                                       *
  121. *       the F68K I/O-functions                                          *
  122. *                                                                       *
  123. ************************************************************************/
  124. long cdecl key_quest()   
  125. {  
  126.         return (long)Bconstat(CONSOLE);
  127.  
  128. }
  129.  
  130. long cdecl key()   
  131. {  
  132.         return (long)Bconin(CONSOLE);
  133. }
  134.  
  135. void cdecl emit(ch)   
  136. long ch;
  137. {
  138.         Bconout(CONSOLE,(int)ch);
  139. }
  140.  
  141.  
  142. long cdecl r_w(buffer,block,flag)   
  143. void *buffer;
  144. long block,flag;
  145. {
  146. int i, dev;
  147. long rootblk=0L, maxblock=0L;
  148. char buf[10];   /* buffer for number conversion */
  149. int handle;
  150. #ifdef DEBUG
  151. char message[100];    /* this is for the errormessage */
  152. #endif
  153.  
  154.         for(i=0; i<roottable[0]; i++)  /* find device */
  155.                 if( (roottable[2*i+1] >= rootblk) && (block >= roottable[2*i+1]))
  156.                         {
  157.                         maxblock += roottable[2*i+2];
  158.                         rootblk = roottable[2*i+1];
  159.                         dev = i;
  160.                         }
  161.                                        
  162.         if(block >= maxblock)   /* block in range? */
  163.             {
  164.              goto bad;
  165.              }
  166.  
  167.     if(Mediach(0) != 0)       /* Disk A only!! */ 
  168.         {
  169.         rewind(device[dev]);
  170.         fclose(device[dev]);
  171.         device[dev]=fopen(devicename[dev],"rb+");
  172.         }
  173.  
  174.     handle = fileno(device[dev]);  /* never trust standard functions! */
  175.  
  176.         if( Fseek((block-rootblk)*BPB,handle,0)!=(block-rootblk)*BPB)
  177.                 {
  178.                 goto bad;
  179.                 }
  180.  
  181.         if(flag!=0L)  
  182.                 {
  183.                 if( Fwrite(handle,BPB,buffer)!=BPB)
  184.                         {
  185.                         goto bad;
  186.                         }
  187.                 }
  188.         else
  189.                 {
  190.                 if( Fread(handle,BPB,buffer)!=BPB)
  191.                         {
  192.                         goto bad;
  193.                         }
  194.                 }
  195.         
  196.         return TRUE;
  197.         
  198. bad:        
  199.  
  200. #ifdef DEBUG
  201. message[0]=0;
  202. strcpy(message,"\n*** F68K loader warning:\
  203.  tried to reach physical block: ");
  204. printf(strcat(message,strcat(ultoa(block,buf,10)," ***\n")));
  205. #endif
  206.     return FALSE;  
  207. }
  208.  
  209.  
  210.  
  211.  
  212. long cdecl readsys(buffer,count)
  213. unsigned long *buffer, count;
  214. {
  215.   
  216.         if ( fread(buffer,count,1,infile) != 1)
  217.                 {
  218.                 return FALSE;
  219.                 }
  220.                         
  221.         return TRUE;
  222. }
  223.  
  224.  
  225. long cdecl writesys(buffer,count)
  226. unsigned long *buffer, count;
  227. {
  228. static FILE *out = NULL;
  229.  
  230.         if(!out)
  231.            if( (out = fopen(outfilename,"wb"))== NULL)    
  232.                    {
  233.                    return FALSE;
  234.                    }
  235.  
  236.         if ( fwrite(buffer,count,1,out) != 1)
  237.                 {
  238.                 return FALSE;
  239.                 }
  240.                         
  241.         return TRUE;
  242. }
  243.  
  244. /************************************************************************
  245. *       end of I/O functions                                            *
  246. ************************************************************************/
  247.  
  248.  
  249.  
  250. void read_paras(roottable)
  251. long *roottable;
  252. {
  253. FILE *paras;
  254. int devices, dev;
  255. long devicesize[MAX_DEVICES];
  256. char infilename[FILENAME_MAX];
  257. int i;
  258. long startblock = 0;
  259.  
  260.  
  261.         if( (paras=fopen(cfgname,"r"))==NULL)  
  262.                 {
  263.                 fprintf(stderr,"*** F68K loader warning: configuration file F68K.CFG not found\n");
  264.                 return;
  265.                 }
  266.         if( !fscanf(paras,"image: %s%*d\n",imagename))
  267.                 fprintf(stderr,"*** F68K loader warning: no imagefile given in F68K.CFG, suppose F68K.IMG\n");
  268.         if( !fscanf(paras,"code: 0x%lx%*d\n",&codesz))
  269.                 fprintf(stderr,"*** F68K loader warning: no codesize given in F68K.CFG, suppose %ld\n",CODESIZE);
  270.         if( !fscanf(paras,"data: 0x%lx%*d\n",&datasz))
  271.                 fprintf(stderr,"*** F68K loader warning: no datasize given in F68K.CFG, suppose %ld\n",DATASIZE);
  272.         if( !fscanf(paras,"input: %s%*d\n", infilename))
  273.                 {
  274.                 fprintf(stderr,"*** F68K loader warning: no input file given in F68K.CFG, suppose F68K.IN\n");
  275.                 strcpy(infilename,"F68K.IN");
  276.                 }
  277.         if( (infile = fopen(infilename,"rb"))==NULL)
  278.                 fprintf(stderr,"*** F68K loader warning: cannot open input file, READSYS not available\n");
  279.         if( !fscanf(paras,"output: %s%*d\n", outfilename))
  280.                 fprintf(stderr,"*** F68K loader warning: no output file given in F68K.CFG, suppose F68K.OUT\n");
  281.         if( !fscanf(paras,"devices: %d%*d\n",&devices))
  282.                 fprintf(stderr,"*** F68K loader warning: no number of devices given in F68K.CFG\n");
  283.         if( devices == 0)
  284.                 fprintf(stderr,"*** F68K loader warning: no block storage device available\n");
  285.         if( devices > MAX_DEVICES )
  286.                 {
  287.                 fprintf(stderr,"*** F68K loader error: too much devices (max. %d devices available)\n"); 
  288.                 exit(0);
  289.                 }
  290.         for(i=0; i<devices; i++)
  291.                 {
  292.                 if( fscanf(paras,"d%d: ",&dev) && (dev>=0) && (dev<MAX_DEVICES))
  293.                         fscanf(paras,"%s%*d\n",devicename[dev]);
  294.                 else
  295.                         {
  296.                         fprintf(stderr,"*** F68K loader error: invalid device specification\n");
  297.                         exit(0);
  298.                         }
  299.                 if( (device[dev]=fopen(devicename[dev],"rb+")) != NULL)
  300.                         {
  301.                         devicesize[dev] = fsize(device[dev]);
  302.                         roottable[2*dev+1] = startblock;
  303.                         roottable[2*(dev+1)] = devicesize[dev]/BPB;
  304. #ifdef DEBUG                        
  305. fprintf(stderr,"*** F68K loader message:  \
  306. D%d: (%s) starts with block #%ld  ***\n",dev,devicename[dev],startblock);
  307. #endif
  308.                         startblock += devicesize[dev]/BPB;      
  309.                         }
  310.                 else
  311.                         {
  312.                         fprintf(stderr,"*** F68K loader warning: device D%d: cannot be accessed\n",dev);        
  313.                         roottable[2*dev+1] = -1;
  314.                         roottable[2*(dev+1)] = 0;
  315.                         }
  316.                 }
  317.         roottable[0] = devices;
  318. #ifdef DEBUG
  319. fprintf(stderr,"\n");
  320. #endif
  321. }
  322.  
  323.  
  324. void read_segments(codeseg,dataseg)
  325. void **codeseg, **dataseg;
  326. {       
  327. FILE *image;
  328.  
  329. struct header
  330. {
  331.         int magic;
  332.         unsigned long codesize;
  333.         unsigned long datasize;
  334.         int dont_care[9];
  335. } header;
  336.  
  337.  
  338.         if( ((*codeseg = malloc(codesz)) == NULL) | 
  339.             ((*dataseg = malloc(datasz)) == NULL))   
  340.                 {
  341.                 fprintf(stderr,"*** F68K loader error:  segments allocation fault\n");
  342.                 exit(-1);
  343.                 }
  344.  
  345.         if( (image=fopen(imagename,"rb")) == NULL )
  346.                 {
  347.                 fprintf(stderr,"*** F68K loader error:  image file not found\n");
  348.                 exit(-1);
  349.                 }
  350.         
  351.         if( read(fileno(image),&header,(long)sizeof(header)) != (long)sizeof(header))
  352.                 {
  353.                 fprintf(stderr,"*** F68K loader error:  image file read error (header)\n");
  354.                 exit(-1);
  355.                 }
  356.  
  357.     if(header.magic != 'JP') 
  358.         {
  359.         fprintf(stderr,"*** F68K loader error:  this is not an F68K image\n");
  360.         exit(-1);
  361.         }
  362.  
  363.         if( read(fileno(image), *codeseg, header.codesize) != header.codesize)
  364.                 {
  365.                 fprintf(stderr,"*** F68K loader error:  image file read error (code)\n");
  366.                 exit(-1);
  367.                 }
  368.         if( read(fileno(image), *dataseg, header.datasize) != header.datasize)
  369.                 {
  370.                 fprintf(stderr,"*** F68K loader error:  image file read error (data)\n");
  371.                 exit(-1);
  372.                 }
  373. }
  374.