home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / language / f68k.zoo / os9 / os9lader.c < prev   
C/C++ Source or Header  |  1992-03-25  |  12KB  |  462 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.     It is possible to use another CFG-File by invoking its name
  9.     in command line: os9lader [ xxx.CFG ].
  10.     
  11.     Works only correct if FORTH-Kernel lays address of FORTH-Paras 
  12.     down on stack before calling I/O     (see CHANGES.TXT 14.11.91)    26FEB92 TB
  13. ********************************************************************/
  14. #define DEBUG
  15.  
  16.  
  17. #include <stdio.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. #define FILENAME_MAX 64
  26.  
  27. #define FALSE (0)
  28. #define TRUE (-1)
  29.  
  30.  
  31. long key_quest();
  32. long key();
  33. void emit();
  34. long r_w();
  35. long writesys();
  36. long readsys();
  37. void read_paras();
  38. void read_segments();
  39. void keymode();
  40. void linemode();
  41.  
  42. char devicename[MAX_DEVICES][FILENAME_MAX];
  43. FILE* device[MAX_DEVICES];
  44. FILE* infile;
  45. long roottable[MAX_DEVICES * 2 + 1]; 
  46.  
  47. long codesz = CODESIZE;
  48. long datasz = DATASIZE; 
  49. char imagename[FILENAME_MAX]   = "F68K.IMG";
  50. char outfilename[FILENAME_MAX] = "F68K.OUT";
  51. char cfgname[FILENAME_MAX]     = "F68K.CFG";
  52.  
  53. char key_buffer;
  54.  
  55.  
  56. handle_signal(signum)
  57. int signum;
  58. {
  59.     linemode();
  60.     exit(0);
  61. }
  62.  
  63.  
  64. void main(argc,argv)
  65. int argc;
  66. char *argv[];
  67. {
  68. char *codeseg,*dataseg;
  69. void (*f68k)();
  70.  
  71. static long _keytable[]        = {1, key};
  72. static long _keyqtable[]    = {1, key_quest};
  73. static long _emittable[]    = {1, emit};
  74. static long _r_wtable[]        = {1, r_w};
  75. static long _readsystable[]    = {1, readsys};
  76. static long _writesystable[]    = {1, writesys};
  77.  
  78. struct _forthparas
  79. {
  80.     long registers[16];    /* to be filled by F68K */
  81. /*    void *forthregs[4]; */    /* A3,A5,A6,A7 for F68K */
  82.     void *data;        /* A3 */
  83.     void *code;        /* A5 */
  84.     void *datastack;    /* A6 */
  85.     void *retstack;      /* A7 */
  86.     void *TIBptr;
  87.     long codelen;
  88.     long datalen;
  89.     void *emittable;
  90.     void *keytable;
  91.     long *keyqtable;
  92.     long *r_wtable;
  93.     long *readsystable;
  94.     long *writesystable;
  95.     long *roottable;
  96. } forthparas; 
  97.  
  98.  
  99.     forthparas.emittable     = _emittable;
  100.     forthparas.keytable     = _keytable;
  101.     forthparas.keyqtable     = _keyqtable;
  102.     forthparas.r_wtable     = _r_wtable;
  103.     forthparas.readsystable = _readsystable;
  104.     forthparas.writesystable= _writesystable;
  105.     forthparas.roottable     = roottable;
  106.  
  107.  
  108.     if(argc==2)  strcpy(cfgname,argv[1]);
  109.  
  110.  
  111.         read_paras(roottable);
  112.         forthparas.codelen    = codesz;
  113.         forthparas.datalen    = datasz; 
  114.        
  115.         read_segments(&codeseg,&dataseg);
  116.         forthparas.code        = codeseg;
  117.         forthparas.data        = dataseg;
  118.         forthparas.datastack = (void*)((long)dataseg+datasz-TIBSIZE);
  119.         forthparas.retstack     = (void*)((long)dataseg+datasz);
  120.         forthparas.TIBptr     = (void*)((long)dataseg+datasz-TIBSIZE);
  121.  
  122.         keymode();
  123.         intercept(handle_signal);
  124.         f68k=(void*)codeseg;        
  125.  
  126.         (*f68k)(0,0,&forthparas);
  127. #asm
  128.         movea.l 56(a7),a6
  129. #endasm
  130.         linemode();
  131.         exit(0);
  132. }
  133.  
  134.  
  135. /************************************************************************
  136. *                                                                       *
  137. *       the F68K I/O-functions                                          *
  138. *                                                                       *
  139. ************************************************************************/
  140. long key_quest()   
  141. {
  142. #asm
  143.         movea.l 20(a7),a6
  144.         movea.l 56(a6),a6
  145. #endasm
  146.         return (_gs_rdy(fileno(stdin)) != -1) ? TRUE : FALSE ;
  147. }
  148.  
  149. long key()   
  150. {  
  151. #asm
  152.         movea.l 20(a7),a6
  153.         movea.l 56(a6),a6
  154. #endasm
  155.         read(fileno(stdin),&key_buffer,1);
  156.         return (key_buffer);
  157. }
  158.  
  159. void emit(chars)   
  160. char chars;
  161. {
  162. #asm
  163.         move.l    20(a7),(a7)
  164.         movea.l 24(a7),a6
  165.         movea.l 56(a6),a6
  166. #endasm
  167.         chars &= 0x7f;
  168.         write(1,&chars,1);
  169. }
  170.  
  171.  
  172. #include <sgstat.h>
  173. struct sgbuf  ttys, ttysnew;    /* for terminal mode setting */
  174.  
  175. static lmode = 0;
  176. #define M_KEY 1
  177. #define M_LINE 2
  178.  
  179. void initline()
  180. {
  181.     if (lmode)
  182.         return;
  183.     if (_gs_opt(0, &ttys) < 0)
  184.         return;
  185.  
  186.     _strass(&ttysnew, &ttys, sizeof(struct sgbuf));
  187.     ttysnew.sg_echo = 0;     /* set for no echoing */ 
  188.     ttysnew.sg_case = 0;     /* allow either case */
  189.     ttysnew.sg_delete = 0;    /* no crt line erasing */
  190.     ttysnew.sg_pause = 0;    /* no page mode */
  191.     ttysnew.sg_bspch = 0;    /* no backspace editing */
  192.     ttysnew.sg_dlnch = 0;    /* no delete line */
  193.     ttysnew.sg_eorch = 20;    /* end of record character ^T in case of bomb */
  194.     ttysnew.sg_eofch = 0;    /* no end of file character */
  195.     ttysnew.sg_rlnch = 0;    /* no repeat line character */
  196.     ttysnew.sg_dulnch = 0;    /* no duplicate line character */
  197.     ttysnew.sg_psch = 0;    /* no pause character */
  198.     ttysnew.sg_kbich = 3;    /* ^C keyboard interrupt character */
  199.     ttysnew.sg_kbach = 0;    /* no keyboard abort character */
  200.     ttysnew.sg_xon = 0;        /* no XON character */
  201.     ttysnew.sg_xoff = 0;    /* no XOFF character */
  202.     ttysnew.sg_tabcr = 0;    /* no tab character */
  203. }
  204.  
  205. void linemode()
  206. {
  207.     initline();
  208.     if (lmode != M_LINE) 
  209.     {
  210.         _ss_opt(0, &ttys);
  211.         lmode = M_LINE;
  212.     }
  213. }
  214.  
  215. void keymode()
  216. {
  217.     initline();
  218.     if (lmode != M_KEY) 
  219.     {
  220.         _ss_opt(0, &ttysnew);
  221.         lmode = M_KEY;
  222.     }
  223. }
  224.  
  225.  
  226. long r_w(buffer,block,flg)   
  227. long buffer,block,flg;
  228. {
  229. int i, dev;
  230. long rootblk=0L, maxblock=0L;
  231. #asm
  232.         move.l    20(a7),(a7)
  233.         move.l  24(a7),4(a7)
  234.         move.l  28(a7),20(a7)
  235.         movea.l 32(a7),a6
  236.         movea.l 56(a6),a6
  237. #endasm
  238.  
  239.         for(i=0; i<roottable[0]; i++)  /* find device */
  240.                 if( (roottable[2*i+1] >= rootblk) && (block >= roottable[2*i+1]))
  241.                         {
  242.                         maxblock += roottable[2*i+2];
  243.                         rootblk = roottable[2*i+1];
  244.                         dev = i;
  245.                         }
  246.                                        
  247.         if(block >= maxblock)   /* block in range? */
  248.             {
  249.              goto bad;
  250.              }
  251.  
  252.  
  253.         if( fseek(device[dev],(block-rootblk)*BPB,0))
  254.                 {
  255.                 goto bad;
  256.                 }
  257.  
  258.         if(flg!=0L)  
  259.                 {
  260.                 if( !fwrite(buffer,BPB,1,device[dev]))
  261.                         {
  262.                         goto bad;
  263.                         }
  264.                 }
  265.         else
  266.                 {
  267.                 if( !fread(buffer,BPB,1,device[dev]))
  268.                         {
  269.                         goto bad;
  270.                         }
  271.                 }
  272.         
  273.         return TRUE;
  274.         
  275. bad:        
  276.  
  277. #ifdef DEBUG
  278. printf("%ld\n*** F68K loader warning: tried to reach physical block: ",block," ***\n");
  279. #endif
  280.     return FALSE;  
  281. }
  282.  
  283.  
  284. long readsys(buffer,count)
  285. unsigned long buffer, count;
  286. {
  287. #asm
  288.         move.l    20(a7),(a7)
  289.         move.l  24(a7),4(a7)
  290.         movea.l 28(a7),a6
  291.         movea.l 56(a6),a6
  292. #endasm
  293.           if ( fread(buffer,count,1,infile) != 1)
  294.                 {
  295.                 return FALSE;
  296.                 }
  297.                         
  298.         return TRUE;
  299. }
  300.  
  301.  
  302. long writesys(buffer,count)
  303. unsigned long buffer, count;
  304. {
  305. static FILE *out = NULL;
  306. #asm
  307.         move.l    20(a7),(a7)
  308.         move.l  24(a7),4(a7)
  309.         movea.l 28(a7),a6
  310.         movea.l 56(a6),a6
  311. #endasm
  312.         if(!out)
  313.            if( (out = fopen(outfilename,"w"))== NULL)    
  314.                    {
  315.                    return FALSE;
  316.                    }
  317.  
  318.         if ( fwrite(buffer,count,1,out) != 1)
  319.                 {
  320.                 return FALSE;
  321.                 }
  322.         fflush(out);                        
  323.         return TRUE;
  324. }
  325.  
  326. /************************************************************************
  327. *       end of I/O functions                                            *
  328. ************************************************************************/
  329.  
  330.  
  331.  
  332. void read_paras(roottable)
  333. long *roottable;
  334. {
  335. FILE *paras;
  336. int devices, dev;
  337. long devicesize[MAX_DEVICES];
  338. char infilename[FILENAME_MAX];
  339. int i;
  340. long startblock = 0;
  341.  
  342.  
  343.         if( (paras=fopen(cfgname,"r"))==NULL)  
  344.                 {
  345.                 fprintf(stderr,"*** F68K loader warning: configuration file F68K.CFG not found\n");
  346.                 return;
  347.                 }
  348.         if( !fscanf(paras,"image: %s%*d\n",imagename))
  349.                 fprintf(stderr,"*** F68K loader warning: no imagefile given in F68K.CFG, suppose F68K.IMG\n");
  350.         if( !fscanf(paras,"code: 0x%lx%*d\n",&codesz))
  351.                 fprintf(stderr,"*** F68K loader warning: no codesize given in F68K.CFG, suppose %ld\n",CODESIZE);
  352.         if( !fscanf(paras,"data: 0x%lx%*d\n",&datasz))
  353.                 fprintf(stderr,"*** F68K loader warning: no datasize given in F68K.CFG, suppose %ld\n",DATASIZE);
  354.         if( !fscanf(paras,"input: %s%*d\n", infilename))
  355.                 {
  356.                 fprintf(stderr,"*** F68K loader warning: no input file given in F68K.CFG, suppose F68K.IN\n");
  357.                 strcpy(infilename,"F68K.IN");
  358.                 }
  359.         if( (infile = fopen(infilename,"r"))==NULL)
  360.                 fprintf(stderr,"*** F68K loader warning: cannot open input file, READSYS not available\n");
  361.         if( !fscanf(paras,"output: %s%*d\n", outfilename))
  362.                 fprintf(stderr,"*** F68K loader warning: no output file given in F68K.CFG, suppose F68K.OUT\n");
  363.         if( !fscanf(paras,"devices: %d%*d\n",&devices))
  364.                 fprintf(stderr,"*** F68K loader warning: no number of devices given in F68K.CFG\n");
  365.         if( devices == 0)
  366.                 fprintf(stderr,"*** F68K loader warning: no block storage device available\n");
  367.         if( devices > MAX_DEVICES )
  368.                 {
  369.                 fprintf(stderr,"*** F68K loader error: too much devices (max. %d devices available)\n"); 
  370.                 exit(0);
  371.                 }
  372.         for(i=0; i<devices; i++)
  373.                 {
  374.                 if( fscanf(paras,"d%d: ",&dev) && (dev>=0) && (dev<MAX_DEVICES))
  375.                         fscanf(paras,"%s%*d\n",devicename[dev]);
  376.                 else
  377.                         {
  378.                         fprintf(stderr,"*** F68K loader error: invalid device specification\n");
  379.                         exit(0);
  380.                         }
  381.                 if( (devicesize[dev]=fsize(devicename[dev])) != -1L)
  382.                         {
  383.                         device[dev] = fopen(devicename[dev],"r+");
  384.                         roottable[2*dev+1] = startblock;
  385.                         roottable[2*(dev+1)] = devicesize[dev]/BPB;
  386.                         startblock += devicesize[dev]/BPB;      
  387.                         }
  388.                 else
  389.                         {
  390.                         fprintf(stderr,"*** F68K loader warning: device D%d: cannot be accessed\n",dev);        
  391.                         roottable[2*dev+1] = -1;
  392.                         roottable[2*(dev+1)] = 0;
  393.                         }
  394.                 }
  395.         roottable[0] = devices;
  396.  
  397. }
  398.  
  399. long fsize(filename)
  400. char *filename;
  401. {
  402. FILE *fnr;
  403. long size;
  404.     if((fnr=fopen(filename,"r")) == 0) return(-1L);
  405.     size=lseek(fileno(fnr),0,2);
  406.     fclose(fnr);
  407.     return(size);
  408. }
  409.  
  410. void read_segments(codeseg,dataseg)
  411. char **codeseg, **dataseg;
  412. {       
  413. FILE *image;
  414.  
  415. struct header
  416. {
  417.         short magic;
  418.         unsigned long codesize;
  419.         unsigned long datasize;
  420.         short dont_care[9];
  421. } header;
  422.  
  423.  
  424.         if( ((*codeseg = malloc(codesz)) == NULL) | 
  425.             ((*dataseg = malloc(datasz)) == NULL))   
  426.                 {
  427.                 fprintf(stderr,"*** F68K loader error:  segments allocation fault\n");
  428.                 exit(-1);
  429.                 }
  430.  
  431.         if( (image=fopen(imagename,"r")) == NULL )
  432.                 {
  433.                 fprintf(stderr,"*** F68K loader error:  image file not found\n");
  434.                 exit(-1);
  435.                 }
  436.         
  437.         if( fread(&header,(long)sizeof(header),1,image) != 1)
  438.                 {
  439.                 fprintf(stderr,"*** F68K loader error:  image file read error (header)\n");
  440.                 exit(-1);
  441.                 }
  442.  
  443.     if(header.magic != (256*'J'+'P')) 
  444.         {
  445.         fprintf(stderr,"*** F68K loader error:  this is not an F68K image\n");
  446.         exit(-1);
  447.         }
  448.  
  449.         if( fread(*codeseg,header.codesize,1,image) != 1)
  450.                 {
  451.                 fprintf(stderr,"*** F68K loader error:  image file read error (code)\n");
  452.                 exit(-1);
  453.                 }
  454.         if( fread(*dataseg,header.datasize,1,image) != 1)
  455.                 {
  456.                 fprintf(stderr,"*** F68K loader error:  image file read error (data)\n");
  457.                 exit(-1);
  458.                 }
  459. }
  460.  
  461.  
  462.