home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / diskutil / mutate / mutate.c < prev    next >
C/C++ Source or Header  |  1990-05-13  |  16KB  |  807 lines

  1. #include <aes.h>
  2. #include <linea.h>
  3. #include <tos.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <ext.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <mydefs.h>
  10. #include "mutate.h"
  11.  
  12. char *pbase;
  13. long ramtop;
  14. long rambot;
  15. int    changed;
  16. int cdrive;
  17. int coffst;
  18.  
  19. #define MODEM 0
  20. #define MODEF 1
  21. #define MODED 2
  22.  
  23. struct
  24.     {
  25.     unt    bps;    /* bytes per sector        */
  26.     unt    spc;    /* sectors per cluster    */
  27.     unt    bpc;    /* bytes per cluster    */
  28.     unt    res;    /*                         */
  29.     unt    fat;    /* number of fats        */
  30.     unt    dir;    /* # of dir entries        */
  31.     unt    sec;    /* # of sectors / disk    */
  32.     unt    spf;    /* # of sectors / fat    */
  33.     unt    spt;    /* # of sectors / track    */
  34.     unt    sid;    /* # of sides            */
  35.     unt    hid;    /* # of hidden            */
  36.     unt    bpe;    /* bytes per fat entry    */
  37.     unt    cpf;    /* clusters per fat        */
  38.     unt cps;    /* clusters per system    */
  39.     unt cpd;    /* clusters per direct.    */
  40.     unt sps;    /* sectors per system    */
  41.     unt spd;    /* sectors per direct.    */
  42.     unt bad;    /* bad clusters on disk    */
  43.     unt dcl;    /* data clusters on disk*/
  44.     unt clu;    /* total clusters/disk    */
  45.     } boot;
  46.  
  47. /***********
  48.     blink cursor at x,y
  49. ***********/
  50. long cblink(int x, int y, int a)
  51.     {
  52.     long cx,cy;
  53.     register int    i;
  54.     
  55.     if (!a)
  56.         cx=(long)x+13+(coffst==0)*(x/4);
  57.     else
  58.         cx=(long)x/2+53;
  59.     cy=(long)y*16+108-coffst;
  60.     while(!Cconis())
  61.         {
  62.         for(i=0;i<16;i++)
  63.             *(pbase+cx+((cy+i)*80))^=0xff;
  64.         if (!Cconis())
  65.             delay(100);
  66.         for(i=0;i<16;i++)
  67.             *(pbase+cx+((cy+i)*80))^=0xff;
  68.         if (!Cconis())
  69.             delay(100);
  70.         }
  71.     return(Crawcin());
  72.     }
  73.  
  74. /***********
  75.     print at x,y
  76. ***********/
  77. void printxy(int x, int y, int a, uch c)
  78.     {
  79.     long cx,cy;
  80.     register int i;
  81.  
  82.     Bconout(2,27);
  83.     Bconout(2,'H');
  84.     Bconout(2,(int)c);
  85.     if (!a)
  86.         cx=(long)x+13+(x/4);
  87.     else
  88.         cx=(long)x/2+53;
  89.     cy=(long)y*16+108;
  90.     for(i=0;i<16;i++)
  91.         {
  92.         *(pbase+cx+((cy+i)*80))=*(pbase+i*80);
  93.         *(pbase+i*80)=0;
  94.         }
  95.     }
  96.  
  97. /***********
  98.     Get a long hex input
  99. ***********/
  100. long getlong(int x, int y, long old, int box, int item)
  101.     {
  102.     int c;
  103.     long k,l;
  104.     int p,done;
  105.     
  106.     l=0;
  107.     p=0;
  108.     done=0;
  109.     while(p<7&&!done)
  110.         {
  111.         sprintf(rs_object[rs_trloc[box]+item].ob_spec.free_string,"%lx",l);
  112.         dial_draw(box,item);
  113.         k=cblink(x+p,y,0);
  114.         c=(int)k;
  115.         if ((c==0)||(k==0xE0008L))
  116.             {
  117.             if (((k==0x4d0000L)||(k==0xE0008L))&&(p>0))
  118.                 {
  119.                 p-=1;
  120.                 l=l>>4;
  121.                 }
  122.             else
  123.                 done=1;
  124.             }
  125.         else if ((done=(c==13))==0)
  126.             {
  127.             if (islower(c)) c=toupper(c);
  128.             if ((c<'0')||(c>'F')||((c>'9')&&(c<'A')))
  129.                 printf("\007");
  130.             else
  131.                 {
  132.                 if (c>'9')
  133.                     c=c-55;
  134.                 else
  135.                     c=c-48;
  136.                 l=((l<<4)|c);
  137.                 ++p;
  138.                 }
  139.             }
  140.         }
  141.     if (c==13)
  142.         return(l);
  143.     else
  144.         return(old);
  145.     }
  146.  
  147. /***********
  148.     Supervisor Peek
  149. ***********/
  150. long speekl;
  151. long speekv;
  152. void speek(void)
  153.     {
  154.     speekv=*(long *)speekl;
  155.     }
  156.  
  157. /***********
  158.     Supervisor Poke
  159. ***********/
  160. void spoke(void)
  161.     {
  162.     *(long *)speekl=speekv;
  163.     }
  164.  
  165. /***********
  166.     Peek a long word
  167. ***********/
  168. long peek(long loc)
  169.     {
  170.     if ((loc<ramtop)&&(loc>rambot))
  171.         return(*(long *)loc);
  172.     else
  173.         {
  174.         speekl=loc;
  175.         Supexec(speek);
  176.         return(speekv);
  177.         }
  178.     }
  179.  
  180. /**********
  181.     Poke a long word
  182. **********/
  183. void poke(long loc, long val)
  184.     {
  185.     if ((loc<ramtop)&&(loc>rambot))
  186.         *(long *)loc=val;
  187.     else
  188.         {
  189.         speekl=loc;
  190.         speekv=val;
  191.         Supexec(spoke);
  192.         }
  193.     }
  194.  
  195. /***********
  196.     Getfile
  197. ***********/
  198. int getfile(uch **buf, long *size)
  199.     {
  200.     int        c,fd;
  201.     long    l;
  202.     static    char *f="FILENAME.EXT";
  203.     static    char *p="A:\\*.*\0                                                 ";
  204.     char    q[128];
  205.     uch        *b;
  206.     
  207.     *p='A'+(char)Dgetdrv();
  208.     fsel_exinput(p,f,&c,"Choose a file to MUTATE!");
  209.     if (c)
  210.         {
  211.         Dsetdrv((int)*p-65);
  212.         strcpy(q,p+2);
  213.         strcpy(strrchr(q,'\\')+1,f);
  214.         if (Fsfirst(q,0)>=0)
  215.             {
  216.             Fgetdta();
  217.             fd=Fopen(q,READ);
  218.             l=filelength(fd);
  219.             if ((b=malloc(l))!=NULL)
  220.                 {
  221.                 if (*buf!=NULL)
  222.                     free(*buf);
  223.                 *buf=b;
  224.                 strcpy(rs_object[rs_trloc[MAIN]+MAINFNAM].ob_spec.free_string,f);
  225.                 dial_draw(MAIN,MAINFNAM);
  226.                 Fread(fd,l,*buf);
  227.                 *size=l;
  228.                 Fclose(fd);
  229.                 return(1);
  230.                 }
  231.             else
  232.                 {
  233.                 Fclose(fd);
  234.                 return(0);
  235.                 }    
  236.             }
  237.         else    
  238.             return(0);
  239.         }
  240.     else
  241.         return(0);
  242.     }
  243.  
  244.  
  245. /***********
  246.     Putfile
  247. ***********/
  248. int putfile(uch *buf, long size)
  249.     {
  250.     int        c,fd;
  251.     static    char *f="FILENAME.EXT";
  252.     static    char *p="A:\\*.*\0                                                 ";
  253.     char    q[128];
  254.     
  255.     *p='A'+(char)Dgetdrv();
  256.     fsel_exinput(p,f,&c,"Choose a file to save the MUTATION!");
  257.     if (c)
  258.         {
  259.         Dsetdrv((int)*p-65);
  260.         strcpy(q,p+2);
  261.         strcpy(strrchr(q,'\\')+1,f);
  262.         fd=1;
  263.         if (Fsfirst(q,0)>=0)
  264.             {
  265.             Fgetdta();
  266.             fd=mess2("Do you wish to","overwrite?","NO","YES",1);
  267.             }
  268.         if (fd)
  269.             {
  270.             Fdelete(f);
  271.             fd=Fcreate(f,0);
  272.             Fclose(fd);
  273.             fd=Fopen(q,WRITE);
  274.             Fwrite(fd,size,buf);
  275.             Fclose(fd);
  276.             return(1);
  277.             }
  278.         else
  279.             return(putfile(buf,size));
  280.         }
  281.     else
  282.         return(0);
  283.     }
  284.  
  285. /****************************
  286.     Check in disk & set info
  287. ****************************/
  288. void dmapdriv(int drive)
  289.     {
  290.     long     e;
  291.     unt        *buf;
  292.  
  293.     buf = (unt *)malloc(0x2000);
  294.     Dsetdrv(drive);
  295.     if (Mediach(drive))
  296.         Getbpb(drive);
  297.     if ((e=Rwabs(READ+2,buf,1,0,drive))!=0)
  298.         {
  299.         mess("Boot read error!");
  300.         messl(e);
  301.         }
  302.     else
  303.         {
  304.         boot.bps = (buf[5]&0x00ff)+(buf[6]&0xff00);
  305.         boot.spc = (buf[6]&0x00ff);
  306.         boot.res = ((buf[7]&0x00ff)<<8)+((buf[7]&0xff00)>>8);
  307.         boot.fat = (buf[8]&0xff00)>>8;
  308.         boot.dir = (buf[8]&0x00ff)+(buf[9]&0xff00);
  309.         boot.sec = (buf[9]&0x00ff)+(buf[10]&0xff00);
  310.         boot.spf = ((buf[11]&0x00ff)<<8)+((buf[11]&0xff00)>>8);
  311.         boot.spt = ((buf[12]&0x00ff)<<8)+((buf[12]&0xff00)>>8);
  312.         boot.sid = ((buf[13]&0x00ff)<<8)+((buf[13]&0xff00)>>8);
  313.         boot.hid = ((buf[14]&0x00ff)<<8)+((buf[14]&0xff00)>>8);
  314.         boot.bpc = (boot.bps * boot.spc);
  315.         boot.spd = (boot.dir / (boot.bps/0x20) * (boot.bps/0x200));
  316.         boot.cpd =((boot.spd +1)/ boot.spc);
  317.         boot.cpf = (boot.spf / boot.spc) * boot.fat * (boot.bps/0x200);
  318.         boot.cps = (boot.cpf + boot.cpd);
  319.         boot.sps =((boot.spf * boot.fat) + boot.spd);
  320.         boot.dcl =((boot.sec-boot.sps)/boot.spc);
  321.         boot.clu = (boot.dcl + boot.cps);
  322.         boot.bpe = 4;
  323.         if (drive < 2) boot.bpe = 3;
  324.         }
  325.     free(buf);
  326.     }
  327.  
  328. /***********
  329.     Check for Update
  330. ***********/
  331. void putbuf(int mode, uch *buf, long boff, long bufsize)
  332.     { 
  333.     long l,m;
  334.     
  335.     if (changed)
  336.         {
  337.         changed=0;
  338.         if (mess2("Do you wish to","make changes permanent","NO","YES",0))
  339.             {
  340.             switch(mode)
  341.                 {
  342.                 case MODEM:
  343.                     for(l=0L;(l<bufsize)&&(l+boff<ramtop);l+=4)
  344.                         poke(l+boff,*((long *)(buf+l)));
  345.                     break;
  346.                 case MODEF:
  347.                     putfile(buf,bufsize);
  348.                     break;
  349.                 case MODED:
  350.                     dmapdriv(cdrive);
  351.                     l=bufsize/boot.bps;
  352.                     m=boff/boot.bps;
  353.                     if (Rwabs(WRITE+2,buf,(int)l,(int)m,cdrive)<0)
  354.                         mess("CAREFUL! Write Error");
  355.                     break;
  356.                 }
  357.             }
  358.         }
  359.     }
  360.  
  361. /***********
  362.     Fill the buffer with data
  363. ***********/
  364. void fillbuf(int mode, uch *buf, long boff, long bufsize)
  365.     {
  366.     long    l,m;
  367.  
  368.     putbuf(mode,buf,boff,bufsize);
  369.     switch (mode)
  370.         {
  371.         case MODEM:
  372.             for(l=0L;l<bufsize;l+=4)
  373.                 *((long *)(buf+l))=peek(l+boff);
  374.             break;
  375.         case MODEF:
  376.             break;
  377.         case MODED:
  378.             dmapdriv(cdrive);
  379.             l=bufsize/boot.bps;
  380.             m=boff/boot.bps;
  381.             if (Rwabs(READ+2,buf,(int)l,(int)m,cdrive)<0)
  382.                 mess("CAREFUL! Read Error");
  383.             break;
  384.         }
  385.     }
  386.  
  387. /***********
  388.     Update the window
  389. ***********/
  390. void update(long offset, long boff, long bufsize, uch *buf)
  391.     {
  392.     int        i,j;
  393.     long    m;
  394.     long    l;
  395.     uch        c;
  396.     char    s[5];
  397.     
  398.     for(i=0,l=0L;(l<0xa0L)&&(l<bufsize-offset);l+=0x10,i++)
  399.         {
  400.         sprintf(rs_object[rs_trloc[MAIN]+MAINSTR0+i].ob_spec.tedinfo->te_ptext,
  401.             "%6lx",l+offset);
  402.         *(rs_object[rs_trloc[MAIN]+MAINSTR0+i].ob_spec.tedinfo->te_ptext+6)=':';
  403.         for(m=0;(m<16)&&(l+m<bufsize-offset);m++)
  404.             {
  405.             c=*(buf+l+m);
  406.             sprintf(s,"%4x",(unt)c);
  407.             if (*(s+2)==' ')
  408.                 *(s+2)='0';
  409.             if (c==0)
  410.                 c=0x2e;
  411.             *(rs_object[rs_trloc[MAIN]+MAINSTR0+i].ob_spec.tedinfo->te_ptext+m+47)=c;
  412.             for(j=0;j<2;j++)
  413.                 *(rs_object[rs_trloc[MAIN]+MAINSTR0+i].ob_spec.tedinfo->te_ptext+j+m*2+m/2+7)=s[j+2];
  414.             }
  415.         }
  416.     sprintf(rs_object[rs_trloc[MAIN]+MAINOFFS].ob_spec.free_string,"%7lx",boff);
  417.     dial_draw(MAIN,MAINWIND);
  418.     dial_draw(MAIN,MAINOFFS);
  419.     }
  420.  
  421. /***********
  422.     Edit entries
  423. ***********/
  424. void edit(uch *buf, long offset, long boff, long bs, int line)
  425.     {
  426.     uch c,d;
  427.     int    p;
  428.     int alpha;
  429.     long    l;
  430.     char    s[5];
  431.     int        valid,j;
  432.  
  433.     c=0;
  434.     p=0;
  435.     alpha=0;
  436.     while(c!=13)
  437.         {
  438.         l=cblink(p,line,alpha);
  439.         c=(int)l;
  440.         if (c==9)
  441.             alpha=1-alpha;
  442.         else if (c==0)
  443.             {
  444.             if (l==0x500000L)
  445.                 ++line;
  446.             else if (l==0x480000L)
  447.                 --line;
  448.             else if (l==0x4b0000L)
  449.                 p-=1+alpha;
  450.             else if (l==0x4d0000L)
  451.                 p+=1+alpha;
  452.             }
  453.         else if (c!=13)
  454.             {
  455.             valid=0;
  456.             if (alpha)
  457.                 valid=1;
  458.             else
  459.                 {
  460.                 if (islower(c)) c=toupper(c);
  461.                 if ((c<'0')||(c>'F')||((c>'9')&&(c<'A')))
  462.                     printf("\007");
  463.                 else
  464.                     {
  465.                     valid=1;
  466.                     if (c>'9')
  467.                         c=c-55;
  468.                     else
  469.                         c=c-48;
  470.                     d=*(buf+p/2+line*16);
  471.                     if (p%2==0)
  472.                         c=(c<<4)|(d&0xf);
  473.                     else
  474.                         c=(d&0xf0)|c;
  475.                     }
  476.                 }
  477.             if (valid)
  478.                 {
  479.                 changed=1;
  480.                 *(buf+p/2+line*16)=c;
  481.                 sprintf(s,"%4x",(unt)c);
  482.                 if (s[2]==' ')
  483.                     s[2]='0';
  484.                 if (c==0)
  485.                     c=0x2e;
  486.                 *(rs_object[rs_trloc[MAIN]+MAINSTR0+line].ob_spec.tedinfo->te_ptext+p/2+47)=c;
  487.                 printxy(p,line,1,c);
  488.                 for(j=0;j<2;j++)
  489.                     *(rs_object[rs_trloc[MAIN]+MAINSTR0+line].ob_spec.tedinfo->te_ptext+2*(p/2)+p/4+7+j)=s[j+2];
  490.                 printxy((p/2)*2,line,0,s[2]);
  491.                 printxy((p/2)*2+1,line,0,s[3]);
  492.                 if (!alpha)
  493.                     c=0;
  494.                 p+=alpha+1;
  495.                 }
  496.             }
  497.         if (p<0)
  498.             {
  499.             p=31;
  500.             --line;
  501.             }
  502.         if (p>31)
  503.             {
  504.             p=0;
  505.             ++line;
  506.             }
  507.         if (line>9)
  508.             line=0;
  509.         if (line<0)
  510.             line=9;
  511.         if (offset+line*16+p/2>=bs)
  512.             {
  513.             p=0;
  514.             line=0;
  515.             }
  516.         }
  517.     update(offset, boff, bs, buf);
  518.     }
  519.  
  520. /***********
  521.     Get ramtop
  522. ***********/
  523. void Ramtop(void)
  524.     {
  525.     rambot=*(long *)0x4faL;
  526.     ramtop=*(long *)0x42eL;
  527.     }
  528.  
  529. /***********
  530.     Update drive
  531. ***********/
  532. void drvupd(void)
  533.     {
  534.     Dsetdrv(cdrive);
  535.     rs_object[rs_trloc[MAIN]+MAINDRIV].ob_spec.obspec.character=cdrive+'A';
  536.     dial_draw(MAIN,MAINDRIV);
  537.     }
  538.  
  539. /*******************************
  540.     Get next valid drive given
  541.     current in (drv) and
  542.     direction (-1,1) in dir
  543. ********************************/
  544. void gvaldrv(int *drv, int dir)
  545.     {
  546.     long    map;
  547.     int        dv;
  548.     
  549.     dv = *drv;
  550.     map = Drvmap();
  551.     do    {
  552.         *drv += dir;
  553.         if (*drv<0)
  554.             *drv = 15;
  555.         if (*drv > 15)
  556.             *drv = 0;
  557.         if (map & (0x1L << *drv))
  558.             break;
  559.         }    while (*drv  != dv);
  560.     }
  561.  
  562. /***********
  563.     Do Info
  564. ***********/
  565. void doinfo(void)
  566.     {
  567.     int x,y,w,h;
  568.     draw_dialog(INFODIAL,&x,&y,&w,&h,1);
  569.     exit_dialog(INFODIAL,x,y,w,h,0);
  570.     erase_dialog(x,y,w,h);
  571.     }
  572.  
  573. /***********
  574.     Do the dialog
  575. ***********/
  576. void dodial(void)
  577.     {
  578.     uch *buf;
  579.     int    x,y,w,h,c;
  580.     long noff,offset,boff,bufsize,limit;
  581.     int mode,omode;
  582.  
  583.     pbase=(char *)Physbase();
  584.     Supexec(Ramtop);
  585.     draw_dialog(MAIN,&x,&y,&w,&h,1);
  586.     mode=MODEM;
  587.     omode=MODEF;
  588.     buf=malloc(0x2000L);
  589.     limit=ramtop;
  590.     offset=0L;
  591.     boff=0L;
  592.     bufsize=0x2000L;
  593.     fillbuf(mode,buf,boff,bufsize);
  594.     update(offset,boff,bufsize,buf+offset);
  595.     drvupd();
  596.     for(;;)
  597.         {
  598.         if (mode != omode)
  599.             {
  600.             omode=mode;
  601.             putbuf(mode,buf,boff,bufsize);
  602.             unselect(MAIN,MAINDISK);
  603.             unselect(MAIN,MAINFILE);
  604.             unselect(MAIN,MAINMEMO);
  605.             switch (mode)
  606.                 {
  607.                 case MODEM:
  608.                     select(MAIN,MAINMEMO);
  609.                     break;
  610.                 case MODED:
  611.                     select(MAIN,MAINDISK);
  612.                     break;
  613.                 case MODEF:
  614.                     select(MAIN,MAINFILE);
  615.                     break;
  616.                 }
  617.             dial_draw(MAIN,MAINMEMO);
  618.             dial_draw(MAIN,MAINDISK);
  619.             dial_draw(MAIN,MAINFILE);
  620.             }
  621.         c=exit_dialog(MAIN,x,y,w,h,0);
  622.         if(c==MAINQUIT)
  623.             {
  624.             putbuf(mode,buf,boff,bufsize);
  625.             break;
  626.             }
  627.         switch (c)
  628.             {
  629.             case MAININFO:
  630.                 erase_dialog(x,y,w,h);
  631.                 doinfo();
  632.                 draw_dialog(MAIN,&x,&y,&w,&h,1);
  633.                 break;
  634.             case MAINBBAR:
  635.                 break;
  636.             case MAINBAR:
  637.                 break;
  638.             case MAINNEXT:
  639.                 switch (mode)
  640.                     {
  641.                     case MODEM:
  642.                         putbuf(mode,buf,boff,bufsize);
  643.                         boff+=bufsize;
  644.                         if (boff>ramtop)
  645.                             boff=ramtop-0x90L;
  646.                         fillbuf(mode,buf,boff,bufsize);
  647.                         update(offset,boff,bufsize,buf+offset);
  648.                         break;
  649.                     case MODED:
  650.                         break;
  651.                     case MODEF:
  652.                         break;
  653.                     }
  654.                 break;
  655.             case MAINPREV:
  656.                 switch (mode)
  657.                     {
  658.                     case MODEM:
  659.                         putbuf(mode,buf,boff,bufsize);
  660.                         boff-=bufsize;
  661.                         if (boff<0L)
  662.                             boff=0L;
  663.                         fillbuf(mode,buf,boff,bufsize);
  664.                         update(offset,boff,bufsize,buf+offset);
  665.                         break;
  666.                     case MODED:
  667.                         break;
  668.                     case MODEF:
  669.                         break;
  670.                     }
  671.                 break;
  672.             case MAINDLES:
  673.                 gvaldrv(&cdrive,-1);
  674.                 drvupd();
  675.                 break;
  676.             case MAINDRIV:
  677.                 if (mode==MODED)
  678.                     {
  679.                     }
  680.                 break;
  681.             case MAINDMOR:
  682.                 gvaldrv(&cdrive,1);
  683.                 drvupd();
  684.                 break;
  685.             case MAINFIND:
  686.                 break;
  687.             case MAINUPDT:
  688.                 putbuf(mode,buf,boff,bufsize);
  689.                 break;
  690.             case MAINMEMO:
  691.                 omode=mode;
  692.                 mode=MODEM;
  693.                 putbuf(omode,buf,boff,bufsize);
  694.                 free(buf);
  695.                 buf=malloc(0x2000);
  696.                 bufsize=0x2000L;
  697.                 limit=ramtop;
  698.                 boff=0L;
  699.                 offset=0L;
  700.                 fillbuf(mode,buf,boff,bufsize);
  701.                 update(offset,boff,bufsize,buf+offset);
  702.                 break;
  703.             case MAINDISK:
  704.                 omode=mode;
  705.                 mode=MODED;
  706.                 putbuf(omode,buf,boff,bufsize);
  707.                 free(buf);
  708.                 buf=malloc(0x2000);
  709.                 bufsize=0x2000L;
  710.                 offset=0L;
  711.                 boff=0L;
  712.                 fillbuf(mode,buf,boff,bufsize);
  713.                 limit=(long)boot.bps*boot.sec;
  714.                 update(offset,boff,bufsize,buf+offset);
  715.                 break;
  716.             case MAINNFNM:
  717.                 if (mode!=MODEF)
  718.                     break;
  719.             case MAINFILE:
  720.                 omode=mode;
  721.                 mode=MODEF;
  722.                 putbuf(omode,buf,boff,bufsize);
  723.                 if (getfile(&buf,&bufsize))
  724.                     {
  725.                     boff=0L;
  726.                     offset=0L;
  727.                     limit=bufsize;
  728.                     update(offset,boff,bufsize,buf+offset);
  729.                     }
  730.                 else
  731.                     mode=omode;
  732.                 break;
  733.             case MAINQUIT:
  734.                 break;
  735.             case MAINSTR0:
  736.             case MAINSTR1:
  737.             case MAINSTR2:
  738.             case MAINSTR3:
  739.             case MAINSTR4:
  740.             case MAINSTR5:
  741.             case MAINSTR6:
  742.             case MAINSTR7:
  743.             case MAINSTR8:
  744.             case MAINSTR9:
  745.                 graf_mouse(ARROW,0);
  746.                 graf_mouse(M_OFF,0);
  747.                 edit(buf+offset,offset,boff,bufsize,c-MAINSTR0);
  748.                 graf_mouse(M_ON,0);
  749.                 graf_mouse(POINT_HAND,0);
  750.                 break;
  751.             case MAINUP:
  752.                 if (offset>0L)
  753.                     {
  754.                     offset-=0x80L;
  755.                     if (offset<0L)
  756.                         offset=0L;
  757.                     update(offset,boff,bufsize,buf+offset);
  758.                     }
  759.                 break;
  760.             case MAINDOWN:
  761.                 if (offset<bufsize)
  762.                     {
  763.                     offset+=0x80L;
  764.                     if (offset>(bufsize-0x90L))
  765.                         offset=(bufsize-0x90L)&0xfffffff7eL;
  766.                     update(offset,boff,bufsize,buf+offset);
  767.                     }
  768.                 break;
  769.             case MAINNOFF:
  770.                 coffst=9;
  771.                 noff=getlong(7,12,offset,MAIN,MAINOFFS);
  772.                 coffst=0;
  773.                 if (((noff>bufsize+boff)||(noff<boff))&&(noff<limit))
  774.                     {
  775.                     putbuf(mode,buf,boff,bufsize);
  776.                     boff=(noff/bufsize)*bufsize;
  777.                     fillbuf(mode,buf,boff,bufsize);
  778.                     }
  779.                 offset=(noff%bufsize)&0xfffffffeL;
  780.                 update(offset,boff,bufsize,buf+offset);
  781.                 if (noff>limit)
  782.                     mess("Beyond limit!");
  783.                 break;
  784.             }
  785.         }
  786.     erase_dialog(x,y,w,h);
  787.     free(buf);
  788.     }
  789.  
  790. /*******************************************************************
  791.                             MAIN
  792. *******************************************************************/
  793. int main(void)
  794.     {
  795.     appl_init();
  796.     linea_init();
  797.        fix_objects();
  798.       doinfo();
  799.        cdrive=Dgetdrv();
  800.        coffst=0;
  801.     graf_mouse(POINT_HAND,0);
  802.     rsrc_load("MUTATE.RSC");
  803.     dodial();
  804.     appl_exit();
  805.     return(0);
  806.      }
  807.