home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / MoreHardware / GALer20.lha / GALer20 / Source / GALer / Optimizer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-05  |  61.1 KB  |  1,986 lines

  1. /******************************************************************************
  2. ** Optimizer.c
  3. *******************************************************************************
  4. **
  5. ** description:
  6. **
  7. ** This file contains the optimizer for the Boolean equations.
  8. **
  9. ** In the first step the syntax of the source file is checked via the routines
  10. ** of the GAL assembler. After this the equations will be coded (bytes instead
  11. ** of strings - this is easier to deal with). In the next step the coded
  12. ** equations will be optimized by use of the Quine-McCluskey algorithm.
  13. ** After this the coded equations are decoded to strings and written in a file.
  14. **
  15. ******************************************************************************/
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22. /********************************* includes **********************************/
  23.  
  24. #include <libraries/mui.h>
  25.  
  26. #include <exec/memory.h>
  27. #include <libraries/dos.h>
  28. #include <libraries/gadtools.h>
  29. #include <libraries/locale.h>
  30. #include <intuition/intuition.h>
  31. #include <ctype.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34.  
  35. #include <proto/locale.h>
  36. #include <proto/intuition.h>
  37. #include <proto/gadtools.h>
  38. #include <proto/exec.h>
  39. #include <proto/graphics.h>
  40. #include <proto/dos.h>
  41. #include <proto/muimaster.h>
  42.  
  43. #include "GALer.h"
  44. #include "Localize.h"
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51. /********************************** defines **********************************/
  52.  
  53. #define TAKEIT_GADID    1
  54. #define FORGETIT_GADID  2
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. /******************************** functions **********************************/
  62. static struct ActBuffer GetProdTermStart(struct ActBuffer pos);
  63.  
  64. static void  KillProdTerm(struct ActBuffer term);
  65.  
  66. static int   OptimizeEqua(struct ActBuffer buff);
  67.  
  68. static int   Resolvente(struct ActBuffer optstart, struct ActBuffer optend,
  69.                         struct ActBuffer alteSchicht);
  70.  
  71. static int   NumOfVar(struct ActBuffer term);
  72.  
  73. static int   AddResolvente(struct ActBuffer pos1, struct ActBuffer pos2,
  74.                            struct ActBuffer equastart,
  75.                            struct ActBuffer *equaend);
  76.  
  77. static int   SearchVar(struct ActBuffer *, struct ActBuffer, UBYTE);
  78.  
  79. static int   WriteNewSource(struct ActBuffer buff, UBYTE *equastart,
  80.                             UBYTE *equaend);
  81.  
  82. static int   CopyEqua(struct ActBuffer from_buff, struct ActBuffer to_buff);
  83.  
  84. static int   PrintEqua(struct ActBuffer buff, struct ActBuffer *filebuff);
  85.  
  86. static int   GetNext(struct ActBuffer *buff);
  87.  
  88. static int   GetNextEqua(struct ActBuffer *buff);
  89.  
  90. static void  PrintOptText(UBYTE *txt);
  91.  
  92. static int   TranslateEqua(struct ActBuffer *buff);
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99. /******************************** variables **********************************/
  100.  
  101. extern  struct  AppString { LONG   as_ID;
  102.                             STRPTR as_Str;
  103.                           };
  104.  
  105. extern  struct  AppString AppStrings[];
  106.  
  107. extern  int     num_of_pins, asmreadyflag, gal_type, num_of_col;
  108. extern  LONG    fsize;
  109. extern  UBYTE   *fbuff;
  110. extern  UBYTE   *actptr, *buffend;
  111. extern  UBYTE   PinNamesOpt[24][10];
  112. extern  char    path[];
  113.  
  114. extern  struct  Pin             actPin;
  115. extern  struct  Catalog         *catalog;
  116.  
  117. extern  APTR    app;
  118.  
  119.  
  120.  
  121.  
  122. UBYTE   OptTxt1[30];
  123.  
  124.  
  125. int     num_of_ORs, num_of_ANDs;
  126. int     numofpins_Opt;
  127.                                 /*oypos: y-Pos. für Text im Optimizer-Window*/
  128.                                 /*scrolls: wie oft gescrollt wurde*/
  129.                                 /*reqflag: Scrollreq. ja oder nein ?*/
  130.  
  131. char    opttitle[] = {"Optimizer"};
  132.  
  133.  
  134. APTR    LV_opt;
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142. /******************************************************************************
  143. ** Optimizer()
  144. *******************************************************************************
  145. ** input:   none
  146. **
  147. ** output:    0:  o.k.
  148. **          <>0:  an error occured
  149. **
  150. ** remarks: This function optimizes the Boolean equations of a source file.
  151. ******************************************************************************/
  152.  
  153. int Optimizer(void)
  154. {
  155.     int     open;                       /* variables for the user interface */
  156.     ULONG   id, signals;
  157.     APTR    win, take_it, forget_it;
  158.     APTR    old_ORs, old_ANDs, opt_ORs, opt_ANDs, equ_num;
  159.  
  160.     UBYTE   *equastart, *equaend;            /* start/end of an equation */
  161.     int     n, equaflag, asmreadyflag2;
  162.     int     gal_type2, num_of_pins2, num_of_col2;
  163.     int     notready;
  164.     char    strng[10];
  165.  
  166.     struct  ActBuffer       AllEquas, OptEqua, FileEquas;
  167.     struct  Buffer          *FirstAllEquas, *FirstOptEqua, *FirstFileEquas;
  168.  
  169.  
  170.                     /* AllEquas:       buffer to store the coded equations    */
  171.                     /* FirstAllEquas:  pointer to the first buffer of the     */
  172.                     /*                 equations                              */
  173.                     /* OptEqua:        buffer in which an optimized equation  */
  174.                     /*                 should be stored                       */
  175.                     /* FirstOptEquas:  pointer to the first buffer in which   */
  176.                     /*                 an optimized equation should be stored */
  177.                     /* FileEquas:      buffer to store the optimized          */
  178.                     /*                 equations in string form(!); this      */
  179.                     /*                 buffer is used to generate the new     */
  180.                     /*                 source file                            */
  181.  
  182.  
  183.     set(app, MUIA_Application_Sleep, TRUE);     /* deactivate the application */
  184.  
  185.  
  186.     asmreadyflag2 = asmreadyflag;      /* save some variables which will be */
  187.     gal_type2     = gal_type;          /* changed when call the assembler   */
  188.     num_of_pins2  = num_of_pins;
  189.     num_of_col2   = num_of_col;
  190.  
  191.     n = AssembleInputFile(OPTIMIZER);  /* syntax check for the source file */
  192.  
  193.     numofpins_Opt = num_of_pins;
  194.     asmreadyflag  = asmreadyflag2;      /* restore variables */
  195.     num_of_pins   = num_of_pins2;
  196.     num_of_col    = num_of_col2;
  197.  
  198.  
  199.  
  200.     if (gal_type == GAL22V10)
  201.     {
  202.         strcpy(&PinNamesOpt[24][0], "AR");  /* define additional "pins" for */
  203.         strcpy(&PinNamesOpt[25][0], "SP");  /* AR and SP                    */
  204.  
  205.         numofpins_Opt += 2;
  206.     }
  207.  
  208.     gal_type = gal_type2;
  209.  
  210.  
  211.  
  212.     if (!n)                         /* no syntax error detected? */
  213.     {
  214.         equastart = actptr;
  215.  
  216.         if (!(FirstAllEquas = (struct Buffer *)
  217.               AllocMem((long)sizeof(struct Buffer), MEMF_PUBLIC|MEMF_CLEAR)))
  218.         {
  219.             FreeMem(fbuff, fsize);          /* buffer for source file */
  220.             ErrorReq(2);                    /* not enough free memory */
  221.             set(app, MUIA_Application_Sleep, FALSE); /* reactivate app. */
  222.  
  223.             return(-1);
  224.         }
  225.  
  226.         AllEquas.ThisBuff = FirstAllEquas;
  227.         AllEquas.Entry    = (UBYTE *)(&FirstAllEquas->Entries[0]);
  228.         AllEquas.BuffEnd  = (UBYTE *)FirstAllEquas + (long)sizeof(struct Buffer);
  229.  
  230.         if (!TranslateEqua(&AllEquas))      /* code the equations */
  231.         {
  232.             equaend = actptr;               /* save pointer to DESCRIPTION */
  233.  
  234.             if (!(FirstFileEquas = (struct Buffer *)
  235.                   AllocMem((long)sizeof(struct Buffer), MEMF_PUBLIC|MEMF_CLEAR)))
  236.             {
  237.                 FreeMem(fbuff, fsize);        /* buffer for source file   */
  238.                 FreeBuffer(FirstAllEquas);    /* buffer for the equations */
  239.                 ErrorReq(2);                  /* not enough free memory   */
  240.                 set(app, MUIA_Application_Sleep, FALSE); /* reactivate  app. */
  241.  
  242.                 return(-1);
  243.             }
  244.  
  245.             FileEquas.ThisBuff = FirstFileEquas;
  246.             FileEquas.Entry    = (UBYTE *)(&FirstFileEquas->Entries[0]);
  247.             FileEquas.BuffEnd  = (UBYTE *)FirstFileEquas +
  248.                                  (long)sizeof(struct Buffer);
  249.  
  250.             if (AddByte(&FileEquas, (UBYTE)0x0A))
  251.             {                                   /* add some returns at the */
  252.                 FreeMem(fbuff, fsize);          /* start of the equations  */
  253.                 FreeBuffer(FirstAllEquas);
  254.                 FreeBuffer(FirstFileEquas);
  255.                 ErrorReq(2);
  256.                 set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  257.  
  258.                 return(-1);
  259.             }
  260.  
  261.             if (AddByte(&FileEquas, (UBYTE)0x0A))
  262.             {
  263.                 FreeMem(fbuff, fsize);
  264.                 FreeBuffer(FirstAllEquas);
  265.                 FreeBuffer(FirstFileEquas);
  266.                 ErrorReq(2);
  267.                 set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  268.  
  269.                 return(-1);
  270.             }
  271.  
  272.  
  273.  
  274.                                     /* make MUI window */
  275.  
  276.                                           /* prepare the string for         */
  277.                                           /* displaying the equation number */
  278.             strcpy(OptTxt1, AppStrings[MSG_OPT_EQUNUM].as_Str);
  279.             strcat(OptTxt1, "     ");
  280.  
  281.             win = WindowObject,
  282.             MUIA_Window_Title, opttitle,
  283.             MUIA_Window_CloseGadget, FALSE,
  284.             MUIA_Window_NoMenus, TRUE,
  285.             MUIA_HelpNode, "Optimizer",
  286.  
  287.                 WindowContents, VGroup,
  288.                     Child, LV_opt = ListviewObject,
  289.                         MUIA_Listview_Input, FALSE,
  290.                         MUIA_Listview_List, ListObject,
  291.                         MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
  292.                         MUIA_List_DestructHook, MUIV_List_DestructHook_String,
  293.                         ReadListFrame,
  294.                         End, 
  295.                     End,
  296.  
  297.                     Child, HGroup,
  298.                         Child, ColGroup(3), GroupFrameT(AppStrings[MSG_STAT_TXT].as_Str),
  299.                             Child, HSpace(0),
  300.                             Child, Label("ORs"),
  301.                             Child, Label("ANDs"),
  302.  
  303.                             Child, LLabel1(AppStrings[MSG_OLD_EQU].as_Str),
  304.                             Child, old_ORs  = Label("    "),
  305.                             Child, old_ANDs = Label("    "),
  306.  
  307.                             Child, LLabel1(AppStrings[MSG_OPT_EQU].as_Str),
  308.                             Child, opt_ORs  = Label("    "),
  309.                             Child, opt_ANDs = Label("    "),
  310.                             End,
  311.  
  312.                         Child, VGroup,
  313.                             Child, equ_num = LLabel(OptTxt1),
  314.  
  315.                             Child, ColGroup(2),
  316.                                 Child, take_it = SimpleButton(AppStrings[MSG_OPT_USE_GAD].as_Str),
  317.  
  318.                                 Child, forget_it = SimpleButton(AppStrings[MSG_OPT_REJECT_GAD].as_Str),
  319.                                 End,
  320.                             End,
  321.                         End,
  322.                     End,
  323.                 End;
  324.  
  325.  
  326.                                             /* set gadget IDs */
  327.  
  328.             DoMethod(take_it, MUIM_Notify, MUIA_Pressed, FALSE,
  329.                      app, 2, MUIM_Application_ReturnID, TAKEIT_GADID);
  330.  
  331.             DoMethod(forget_it, MUIM_Notify, MUIA_Pressed, FALSE,
  332.                      app, 2, MUIM_Application_ReturnID, FORGETIT_GADID);
  333.  
  334.  
  335.                                                 /* init cycle chain */
  336.  
  337.             DoMethod(win, MUIM_Window_SetCycleChain, take_it, forget_it, NULL);
  338.  
  339.  
  340.  
  341.  
  342.             if (!win)                    /* failed to create window object? */
  343.             {
  344.                 FreeMem(fbuff, fsize);       /* buffer of source file     */
  345.                 FreeBuffer(FirstAllEquas);   /* buffer of coded equations */
  346.                 FreeBuffer(FirstFileEquas);  /* buffer of uncoded equ.    */
  347.                 ErrorReq(12);
  348.                 set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  349.  
  350.                 return(-1);
  351.             }
  352.             else
  353.             {
  354.                 DoMethod(app, OM_ADDMEMBER, win);  /* add win to application */
  355.  
  356.                 set(win, MUIA_Window_Open, TRUE);       /* open window */
  357.                 get(win, MUIA_Window_Open, &open);
  358.  
  359.                 if (!open)              /* failed to open the window? */
  360.                 {
  361.                     FreeMem(fbuff, fsize);       /* buffer of source file    */
  362.                     FreeBuffer(FirstAllEquas);   /* buffer of coded equations*/
  363.                     FreeBuffer(FirstFileEquas);  /* buffer of uncoded equ.   */
  364.  
  365.                     set(win, MUIA_Window_Open, FALSE);       /* close window */
  366.                     DoMethod(app, OM_REMMEMBER, win);        /* remove win   */
  367.                     MUI_DisposeObject(win);                  /* delete object*/
  368.                     set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  369.  
  370.                     return(-1);
  371.                 }
  372.             }
  373.  
  374.  
  375.  
  376.  
  377.             AllEquas.ThisBuff = FirstAllEquas;
  378.             AllEquas.Entry    = (UBYTE *)(&FirstAllEquas->Entries[0]);
  379.             AllEquas.BuffEnd  = (UBYTE *)FirstAllEquas +
  380.                                 (long)sizeof(struct Buffer);
  381.             n = 0;
  382.  
  383.             equaflag = TRUE;        /* there are equations */
  384.  
  385.  
  386.             while (equaflag)        /* as long as there are equations */
  387.             {
  388.                 DoMethod(LV_opt, MUIM_List_Clear);      /* clear listview */
  389.  
  390.                 PrintOptText(AppStrings[MSG_OLD_EQU].as_Str);  /* display the */
  391.                 PrintEqua(AllEquas, NULL);                     /* old equa.   */
  392.  
  393.                 sprintf(strng, "%d", num_of_ORs);           /* statistics */
  394.                 set(old_ORs, MUIA_Text_Contents, strng);
  395.  
  396.                 sprintf(strng, "%d", num_of_ANDs);
  397.                 set(old_ANDs, MUIA_Text_Contents, strng);
  398.  
  399.                 set(opt_ORs,  MUIA_Text_Contents, "-");
  400.                 set(opt_ANDs, MUIA_Text_Contents, "-");
  401.  
  402.  
  403.                 if (!(FirstOptEqua = (struct Buffer *)
  404.                     AllocMem((long)sizeof(struct Buffer), MEMF_PUBLIC|MEMF_CLEAR)))
  405.                 {
  406.                     FreeMem(fbuff, fsize);       /* buffer of source file     */
  407.                     FreeBuffer(FirstAllEquas);   /* buffer of coded equations */
  408.                     FreeBuffer(FirstFileEquas);  /* buffer of uncoded equ.    */
  409.  
  410.                     set(win, MUIA_Window_Open, FALSE);       /* close window */
  411.                     DoMethod(app, OM_REMMEMBER, win);        /* remove win   */
  412.                     MUI_DisposeObject(win);                  /* delete object*/
  413.                     set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  414.  
  415.                     ErrorReq(2);                 /* out of memory */
  416.  
  417.                     return(-1);
  418.                 }
  419.  
  420.                 OptEqua.ThisBuff = FirstOptEqua;
  421.                 OptEqua.Entry    = (UBYTE *)(&FirstOptEqua->Entries[0]);
  422.                 OptEqua.BuffEnd  = (UBYTE *)FirstOptEqua +
  423.                                    (long)sizeof(struct Buffer);
  424.  
  425.                             /* copy an equation into the optimizer buffer */
  426.  
  427.                 if (CopyEqua(AllEquas, OptEqua))
  428.                 {
  429.                     FreeMem(fbuff, fsize);
  430.                     FreeBuffer(FirstAllEquas);
  431.                     FreeBuffer(FirstOptEqua);
  432.                     FreeBuffer(FirstFileEquas);
  433.  
  434.                     set(win, MUIA_Window_Open, FALSE);       /* close window */
  435.                     DoMethod(app, OM_REMMEMBER, win);        /* remove win   */
  436.                     MUI_DisposeObject(win);                  /* delete object*/
  437.                     set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  438.  
  439.                     ErrorReq(2);
  440.  
  441.                     return(-1);
  442.                 }
  443.  
  444.  
  445.                                 /* try to optimize one equation */
  446.  
  447.                 set(win, MUIA_Window_Title, AppStrings[MSG_OPT_WAIT].as_Str);
  448.  
  449.                 set(app, MUIA_Application_Sleep, TRUE); /* deactivate the     */
  450.                                                         /* optimizer's window */
  451.  
  452.                 if (OptimizeEqua(OptEqua))
  453.                 {
  454.                     FreeMem(fbuff, fsize);
  455.                     FreeBuffer(FirstAllEquas);
  456.                     FreeBuffer(FirstOptEqua);
  457.                     FreeBuffer(FirstFileEquas);
  458.  
  459.                     set(win, MUIA_Window_Open, FALSE);       /* close window */
  460.                     DoMethod(app, OM_REMMEMBER, win);        /* remove win   */
  461.                     MUI_DisposeObject(win);                  /* delete object*/
  462.                     set(app, MUIA_Application_Sleep, FALSE); /* reactivate   */
  463.  
  464.                     ErrorReq(2);
  465.  
  466.                     return(-1);
  467.                 }
  468.  
  469.                 set(app, MUIA_Application_Sleep, FALSE); /* reactivate the    */
  470.                                                          /* optimizer's window*/
  471.                 set(win, MUIA_Window_Title, opttitle);
  472.  
  473.  
  474.                 PrintOptText(" ");                       /* add an empty line */
  475.  
  476.                 PrintOptText(AppStrings[MSG_OPT_EQU].as_Str);  /* display the */
  477.                 PrintEqua(OptEqua, NULL);                      /* old equa.   */
  478.  
  479.                 sprintf(strng, "%d", num_of_ORs);           /* statistics */
  480.                 set(old_ORs, MUIA_Text_Contents, strng);
  481.  
  482.                 sprintf(strng, "%d", num_of_ANDs);
  483.                 set(old_ANDs, MUIA_Text_Contents, strng);
  484.  
  485.                 sprintf(strng, "%d", num_of_ORs);
  486.                 set(opt_ORs, MUIA_Text_Contents, strng);
  487.  
  488.                 sprintf(strng, "%d", num_of_ANDs);
  489.                 set(opt_ANDs, MUIA_Text_Contents, strng);
  490.  
  491.                 n++;
  492.                 strcpy(OptTxt1, AppStrings[MSG_OPT_EQUNUM].as_Str);
  493.                 sprintf(strng, " %d: ", n);
  494.                 strcat(OptTxt1, (const char*)strng);
  495.                 set(equ_num, MUIA_Text_Contents, OptTxt1);
  496.  
  497.  
  498.  
  499.                 notready = 1;
  500.  
  501.                 while (notready)
  502.                 {
  503.                     id = DoMethod(app, MUIM_Application_Input, &signals);
  504.  
  505.                     switch (id)
  506.                     {                                   /* take this    */
  507.                         case TAKEIT_GADID:              /* optimization */
  508.                             PrintEqua(OptEqua, &FileEquas);
  509.                             notready = 0;
  510.  
  511.                             break;
  512.  
  513.                                                         /* don't take this */
  514.                         case FORGETIT_GADID:            /* optimization    */
  515.                             PrintEqua(AllEquas, &FileEquas);
  516.                             notready = 0;
  517.  
  518.                             break;
  519.                     }
  520.  
  521.                     if (notready && signals)
  522.                         Wait(signals);              /* wait for the next event */
  523.                 }
  524.  
  525.                 FreeBuffer(FirstOptEqua);
  526.  
  527.                 equaflag = GetNextEqua(&AllEquas);
  528.             }
  529.  
  530.  
  531.  
  532.                                             /* generate new source file */
  533.  
  534.             FileEquas.ThisBuff = FirstFileEquas;
  535.             FileEquas.Entry    = (UBYTE *)(&FirstFileEquas->Entries[0]);
  536.             FileEquas.BuffEnd  = (UBYTE *)FirstFileEquas +
  537.                                  (long)sizeof(struct Buffer);
  538.  
  539.             if (MyFileReq(AppStrings[MSG_WRITE_SOURCE].as_Str, ".pld", YES, SAVE))
  540.             {
  541.                 PrintText(AppStrings[MSG_WRITE_OPTSOURCE].as_Str, 1);
  542.  
  543.                 if (WriteNewSource(FileEquas, equastart, equaend))
  544.                 {
  545.                     PrintText(AppStrings[MSG_ERROR].as_Str,0);
  546.  
  547.                     TxtRequest(AppStrings[MSG_WRITE_ERR].as_Str,
  548.                                AppStrings[MSG_CANCEL_GAD].as_Str, NULL);
  549.                 }
  550.                 else
  551.                     PrintText(AppStrings[MSG_LOWER_OK].as_Str, 0);
  552.  
  553.             }
  554.  
  555.             FreeMem(fbuff, fsize);      /* buffer for source file */
  556.             FreeBuffer(FirstFileEquas); /* buffer for uncoded optimized */
  557.                                         /* equations                    */
  558.  
  559.             set(win, MUIA_Window_Open, FALSE);      /* close window */
  560.   
  561.             DoMethod(app, OM_REMMEMBER, win);       /* remove win from app. */
  562.  
  563.             MUI_DisposeObject(win);                 /* delete window object */
  564.  
  565.         }
  566.  
  567.         FreeBuffer(FirstAllEquas);
  568.  
  569.     }
  570.  
  571.     set(app, MUIA_Application_Sleep, FALSE);    /* reactivate application */
  572.  
  573.  
  574.     return(0);
  575. }
  576.  
  577.  
  578.  
  579.  
  580.  
  581. /******************************************************************************
  582. ** GetProdTermStart()
  583. *******************************************************************************
  584. ** input:   pos     pointer to a product term
  585. **
  586. ** output:          pointer to the beginning of the product term
  587. **
  588. ** remarks: This function searches for the start of a product term.
  589. ******************************************************************************/
  590.  
  591. static struct ActBuffer GetProdTermStart(struct ActBuffer pos)
  592. {
  593.  
  594.     while(*pos.Entry)
  595.     {
  596.         if (IsOR(*pos.Entry))
  597.         {
  598.             IncPointer(&pos);
  599.             return(pos);
  600.         }
  601.  
  602.         DecPointer(&pos);
  603.     }
  604.  
  605.     IncPointer(&pos);
  606.  
  607.     return(pos);
  608. }
  609.  
  610.  
  611.  
  612.  
  613.  
  614. /******************************************************************************
  615. ** KillProdTerm()
  616. *******************************************************************************
  617. ** input:   term    pointer to the term
  618. **                  the product term is replaced by an EQUSKIP
  619. **
  620. ** output:  none
  621. **
  622. ** remarks: This function removes a product term from an equation.
  623. ******************************************************************************/
  624.  
  625. static void KillProdTerm(struct ActBuffer term)
  626. {
  627.     struct  ActBuffer  start;
  628.  
  629.  
  630.     start = term;
  631.  
  632.     while(*term.Entry && (!IsOR(*term.Entry)))
  633.     {
  634.         *term.Entry = EQUASKIP;
  635.         IncPointer(&term);
  636.     }
  637.  
  638.  
  639.     if (IsOR(*term.Entry))
  640.         *term.Entry = EQUASKIP;
  641.  
  642.     if (!*term.Entry)
  643.     {
  644.         while((*start.Entry) && (!IsOR(*start.Entry)))
  645.             DecPointer(&start);
  646.  
  647.         if (IsOR(*start.Entry))
  648.             *start.Entry = EQUASKIP;
  649.     }
  650. }
  651.  
  652.  
  653.  
  654.  
  655.  
  656. /******************************************************************************
  657. ** OptimizeEqua()
  658. *******************************************************************************
  659. ** input:   buff        pointer to the equations
  660. **
  661. ** output:    0:  o.k.
  662. **           -1:  not enough free memory
  663. **
  664. ** remarks: This function is the main function where the equations are
  665. **          optimized.
  666. ******************************************************************************/
  667.  
  668. static int OptimizeEqua(struct ActBuffer buff)
  669. {
  670.     int     varfound, prodfound, result;
  671.     UBYTE   merker;
  672.  
  673.     struct  ActBuffer optend, pos1, pos2, prodterm1, prodterm2;
  674.  
  675.  
  676.  
  677.     optend = buff;
  678.  
  679.     while (*optend.Entry != EQUAEND)        /* search the end of equation */
  680.         IncPointer (&optend);
  681.  
  682.     *optend.Entry = 0;                  /* signify the end of the equation */
  683.                                         /* instead of an EQUAEND with a 0  */
  684.  
  685.                                         /* signify the beginning of the */
  686.                                         /* equation with a 0 too        */
  687.  
  688.     IncPointer (&buff);                 /* first entry is the output pin */
  689.                                         /* so skip it                    */
  690.  
  691.     if (!(*buff.Entry == 'T' || *buff.Entry == 'R' || *buff.Entry == 'E'
  692.         ||*buff.Entry == 'C' || *buff.Entry == 'S' || *buff.Entry == 'P'))
  693.         DecPointer (&buff);             /* consider suffix */
  694.  
  695.  
  696.     merker = *buff.Entry;               /* Zeichen merken */
  697.  
  698.     *buff.Entry = 0;                    /* Markierung setzen */
  699.                                         /* optend = Gleichungsende */
  700.     IncPointer (&buff);                 /* Zeiger auf erstes Zeichen */
  701.  
  702.     if (!*buff.Entry)                   /* no character there? */
  703.     {
  704.         if (AddByte(&buff, (UBYTE)(numofpins_Opt/2))) /* GND eintragen      */
  705.             return(-1);                               /* und Gleichungsende */
  706.  
  707.         *buff.Entry = EQUAEND;
  708.  
  709.         DecPointer(&buff);
  710.         DecPointer(&buff);
  711.  
  712.         *buff.Entry = merker;
  713.  
  714.         return(0);                      /* finished */
  715.     }
  716.  
  717.  
  718.     if (result = Resolvente(buff, optend, buff))
  719.     {                                           /* Resolventen bilden  */
  720.         if (result == -1)                       /* Fehler aufgetreten? */
  721.             return(-1);                         /* ja, dann Fehlercode */
  722.         else
  723.         {
  724.             if (AddByte(&buff, (UBYTE)numofpins_Opt))  /* VCC eintragen      */
  725.                 return(-1);                            /* und Gleichungsende */
  726.  
  727.             *buff.Entry = EQUAEND;
  728.  
  729.             DecPointer(&buff);
  730.             DecPointer(&buff);
  731.  
  732.             *buff.Entry = merker;
  733.  
  734.             return(0);                          /* fertig */
  735.         }
  736.     }
  737.  
  738.  
  739.     optend = buff;
  740.  
  741.     while (*optend.Entry)                   /* search end of equation */
  742.         IncPointer(&optend);
  743.  
  744.                 /*Absorptions-Gesetz anwenden: a + a * b <=> a */
  745.                 /*Prinzip: Es wird der Produktterm "prodterm1" mit allen*/
  746.                 /*andern ("prodterm2") verglichen und untersucht, ob einer*/
  747.                 /*ein Teil von diesem ist. Wenn ja, wird der andere Produkt-*/
  748.                 /*term gelöscht (mit EQUASKIP).*/
  749.  
  750.     pos1 = prodterm1 = buff;
  751.  
  752.     for (;;)
  753.     {
  754.         pos2 = buff;
  755.  
  756.         while (*pos2.Entry == EQUASKIP)      /* gelöschte Produktterme */
  757.             IncPointer(&pos2);               /* überspringen           */
  758.  
  759.         for(;;)
  760.         {
  761.             varfound = 0;
  762.  
  763.             while (*prodterm1.Entry == EQUASKIP)  /* gelöschte Produktterme */
  764.                 IncPointer(&prodterm1);           /* überspringen           */
  765.  
  766.             while (*pos2.Entry)
  767.             {                                        /* in der Gleichung nach */
  768.                 if (*pos2.Entry == *prodterm1.Entry) /* der Variable suchen,  */
  769.                 {                                    /* die als erstes im     */
  770.                     varfound = 1;                    /* Produktterm steht     */
  771.                     break;
  772.                 }
  773.  
  774.                 IncPointer(&pos2);
  775.             }
  776.  
  777.             if (!varfound)                  /* for-Schleife abbrechen, wenn */
  778.                 break;                      /* keine entsprechende Variable */
  779.                                             /* gefunden wurde               */
  780.  
  781.             prodterm2 = GetProdTermStart(pos2);  /* Prod.term-Anfang suchen */
  782.  
  783.             while (*prodterm2.Entry == EQUASKIP)    /* gelöschte Prod.terme */
  784.                 IncPointer(&prodterm2);             /* überspringen         */
  785.  
  786.             if ((prodterm1.Entry != prodterm2.Entry) ||
  787.                 (prodterm1.ThisBuff != prodterm2.ThisBuff) ||
  788.                 (prodterm1.BuffEnd != prodterm2.BuffEnd))
  789.             {
  790.                 pos1 = prodterm1;     /* Prod.terme miteinander vergleichen */
  791.  
  792.                 for (;;)
  793.                 {
  794.                     pos2      = prodterm2;
  795.                     prodfound = 0;
  796.  
  797.                     for (;;)
  798.                     {
  799.                         if (*pos1.Entry == *pos2.Entry)
  800.                         {
  801.                             prodfound = 1;
  802.                             break;
  803.                         }
  804.  
  805.                         IncPointer(&pos2);
  806.  
  807.                         if ((*pos2.Entry) && (!IsOR(*pos2.Entry)) &&
  808.                             (*pos2.Entry != EQUASKIP))
  809.                             IncPointer(&pos2);
  810.                         else
  811.                             break;
  812.                     }
  813.  
  814.                     if (!prodfound)
  815.                         break;
  816.  
  817.                     IncPointer(&pos1);
  818.  
  819.                     if ((*pos1.Entry) && (!IsOR(*pos1.Entry)) &&
  820.                         (*pos1.Entry != EQUASKIP))
  821.                         IncPointer(&pos1);
  822.                     else
  823.                         break;
  824.                 }
  825.  
  826.                 if (prodfound)
  827.                     KillProdTerm(prodterm2);
  828.             }
  829.  
  830.             if (*pos2.Entry)
  831.                 IncPointer(&pos2);
  832.         }
  833.  
  834.         while((!IsOR(*pos1.Entry)) && (*pos1.Entry)) /* nächsten Prod.term */
  835.             IncPointer(&pos1);                       /* suchen             */
  836.  
  837.         if (!*pos1.Entry)                         /* kein Prod.term mehr da */
  838.             break;                                /* dann fertig            */
  839.  
  840.         IncPointer(&pos1);
  841.  
  842.         prodterm1 = pos1;
  843.     }
  844.  
  845.     DecPointer(&buff);
  846.     *buff.Entry = merker;                   /* Gleichung wieder herstellen */
  847.  
  848.     if (AddByte(&optend, (UBYTE)EQUAEND))   /* Gleichungsende wieder durch */
  849.         return(-1);                         /* EQUAEND markieren           */
  850.  
  851.     if (AddByte(&optend, (UBYTE)0))
  852.         return(-1);
  853.  
  854.  
  855.     return(0);
  856. }
  857.  
  858.  
  859.  
  860.  
  861.  
  862. /******************************************************************************
  863. ** Resolvente()
  864. *******************************************************************************
  865. ** input:   optstart        pointer to the start of the equation
  866. **          optend          pointer to the end of the equation
  867. **          alteSchicht     pointer to previous "Schicht"
  868. **
  869. ** output:    0:  o.k.
  870. **            1:  A + /A (=VCC) found, result of equation is always TRUE
  871. **           -1:  not enough free memory
  872. **
  873. ** remarks: hängt eine neue Schicht von Resolventen an die zu optimierende
  874. **          Gleichung an (I don't know how to translate this... ;-))
  875. **
  876. ******************************************************************************/
  877.  
  878. static int Resolvente(struct ActBuffer optstart,
  879.                       struct ActBuffer optend,
  880.                       struct ActBuffer alteSchicht)
  881. {
  882.     int     result, flag, resflag;          /* resflag: neue Resolvente */
  883.     UBYTE   var;                            /* gefunden?                */
  884.  
  885.     struct  ActBuffer  pos1, pos2, neueSchicht;
  886.  
  887.                                         /* neueSchicht: zeigt auf Stelle, an */
  888.                                         /* der weitere Resolventen angefügt  */
  889.                                         /* werden können (Ende)              */
  890.  
  891.     if ((IsOR(*alteSchicht.Entry)) || (IsAND(*alteSchicht.Entry)))
  892.         IncPointer(&alteSchicht);
  893.  
  894.     resflag     = 0;                    /* lokale Variablen initialisieren */
  895.     pos1        = alteSchicht;
  896.     neueSchicht = optend;
  897.  
  898.  
  899.     for (;;)
  900.     {
  901.         var = *pos1.Entry;                  /* Variable (Pinnummer) holen */
  902.  
  903.         if (var & NEGATION)                 /* Variable negieren */
  904.             var = var & (~NEGATION);
  905.         else
  906.             var = var | NEGATION;
  907.  
  908.         pos2 = optstart;                    /* suche nach "/var" */
  909.  
  910.         for(;;)
  911.         {
  912.             if (!SearchVar(&pos2, neueSchicht, var))
  913.             {
  914.                 result = AddResolvente(pos1, pos2, optstart, &optend);
  915.  
  916.                 flag = 0;           /* Wenn die Variable gefunden wurde,   */
  917.                                     /* wird pos2 auf den nächsten Produkt- */
  918.                                     /* term gestellt. Wenn keiner da ist,  */
  919.                                     /* bleibt flag 0 und weiter unten er-  */
  920.                                     /* folgt dann der Abbruch (if(!flag).. */
  921.  
  922.                 while (pos2.Entry != neueSchicht.Entry)
  923.                 {
  924.                     if (IsOR(*pos2.Entry))
  925.                     {
  926.                         flag = 1;
  927.                         IncPointer(&pos2);
  928.                         break;
  929.                     }
  930.  
  931.                     IncPointer (&pos2);
  932.                 }
  933.  
  934.                 if (!result)
  935.                     resflag = 1;
  936.                 else
  937.                 {
  938.                     if (result == 2)    /* A + /A gefunden? => Ausdruck wahr */
  939.                         return(1);      /* dann fertig                       */
  940.  
  941.                     if (result == -1)
  942.                         return(-1);
  943.                 }
  944.  
  945.                 if (!flag)              /* kein Produktterm mehr da? */
  946.                     break;              /* dann Abbruch              */
  947.             }
  948.             else
  949.                 break;
  950.         }
  951.  
  952.  
  953.         IncPointer(&pos1);              /* Operator überspringen und pos1    */
  954.                                         /* auf nächste Variable, falls nicht */
  955.                                         /* bereits der neue Schichtanfang    */
  956.                                         /* erreicht wurde, sonst Abbruch     */
  957.         if (pos1.Entry != neueSchicht.Entry)
  958.             IncPointer(&pos1);
  959.         else
  960.             break;
  961.     }
  962.  
  963.  
  964.     if (!resflag)                       /* wurde neue Resolvente gefunden? */
  965.         return(0);                      /* nein, dann fertig               */
  966.     else                                /* ja, dann Rekursion              */
  967.         return (Resolvente(optstart, optend, neueSchicht));
  968.  
  969.     return 0;                   /* just to keep the compiler happy */
  970. }
  971.  
  972.  
  973.  
  974.  
  975.  
  976. /******************************************************************************
  977. ** NumOfVar()
  978. *******************************************************************************
  979. ** input:   term    pointer to the product term
  980. **
  981. ** output:          number of variables
  982. **
  983. ** remarks: This function returns the number of variables of a product
  984. **          term.
  985. ******************************************************************************/
  986.  
  987. static int NumOfVar(struct ActBuffer term)
  988. {
  989.     int     numofvar;
  990.  
  991.  
  992.     numofvar = 0;
  993.  
  994.     for (;;)
  995.     {
  996.         numofvar++;
  997.  
  998.         IncPointer(&term);
  999.  
  1000.         if (!*term.Entry || (IsOR(*term.Entry)))
  1001.             break;
  1002.  
  1003.         IncPointer(&term);
  1004.     }
  1005.  
  1006.     return (numofvar);
  1007. }
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013. /******************************************************************************
  1014. ** AddResolvente()
  1015. *******************************************************************************
  1016. ** input:   pos1, pos2      ActBuffer structure
  1017. **          equastart       start of equation
  1018. **          equaend         pointer(!) to end of equation
  1019. **
  1020. ** output:      0: es wurde eine Resolvente gebildet und angehängt
  1021. **                 equaend zeigt auf neues Ende
  1022. **              1: keine Resolvente
  1023. **              2: A + /A wurde gefunden (VCC -> fertig)
  1024. **             -1: Fehler, kein Speicher
  1025. **
  1026. ** remarks: Fügt die beiden Produktterme in die "pos1" und "pos2"
  1027. **        zeigt zusammen, wobei die Variablen (Pinnummern) die unter "pos1"
  1028. **        und "pos2" stehen nicht berücksichtigt werden. Dann wird untersucht,
  1029. **        ob der neuentstandene Produktterm schon in der Gleichung steht.
  1030. **        Wenn nicht, wird der Produktterm an "equaend" angehängt.
  1031. **        Eine neue Resolvente ist geboren - welch' Dramatik.
  1032. ******************************************************************************/
  1033.  
  1034. static int AddResolvente(struct ActBuffer pos1, struct ActBuffer pos2,
  1035.                          struct ActBuffer equastart, struct ActBuffer *equaend)
  1036. {
  1037.     int    n, i, numofvar, numofvar1, numofvar2;
  1038.     int    found;
  1039.  
  1040.     UBYTE  *termbuff, *term, entry;
  1041.  
  1042.     struct ActBuffer  pos, res, res1, res2, prodterm, nextprodterm;
  1043.  
  1044.  
  1045.  
  1046.     res1 = GetProdTermStart(pos1);    /* ActBuffer-Struktur für den         */
  1047.     res2 = GetProdTermStart(pos2);    /* jeweiligen Produkttermanfang holen */
  1048.  
  1049.     if ((res1.Entry == res2.Entry) && (res1.ThisBuff == res2.ThisBuff) &&
  1050.         (res1.BuffEnd == res1.BuffEnd))
  1051.         return(1);
  1052.  
  1053.     numofvar1 = NumOfVar(res1);       /* Anzahl der benötigten Bytes     */
  1054.     numofvar2 = NumOfVar(res2);       /* für die beiden Prod.terme holen */
  1055.  
  1056.     if (!(termbuff = (UBYTE *)AllocMem((long)(numofvar1 + numofvar2 + 1),
  1057.                                        MEMF_PUBLIC|MEMF_CLEAR)))
  1058.         return(-1);
  1059.  
  1060.                                      /* hier werden die beiden Produktterme */
  1061.     numofvar = numofvar1;            /* res1 und res2 zusammengehängt und   */
  1062.     res      = res1;                 /* in "termbuff" abgelegt (ohne '*'!)  */
  1063.     pos      = pos1;
  1064.  
  1065.                                      /* zwei Produktterme */
  1066.     for (i = 0; i < 2; i++)
  1067.     {
  1068.         for (n=0; n<numofvar; n++)
  1069.         {
  1070.             if (res.Entry != pos.Entry)
  1071.             {
  1072.                 term  = termbuff;    /* keine doppelten Pins zulassen */
  1073.                 entry = *res.Entry;
  1074.                 found = 0;
  1075.  
  1076.                 while (*term)
  1077.                 {
  1078.                                             /* "a * /a" nicht zulassen */
  1079.                     if (entry & NEGATION)
  1080.                     {
  1081.                         if (*term == (entry & (~NEGATION)))
  1082.                         {
  1083.                             FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  1084.                             return(1);
  1085.                         }
  1086.                     }
  1087.                     else
  1088.                     {
  1089.                         if (*term == entry | NEGATION)
  1090.                         {
  1091.                             FreeMem(termbuff, (long)(numofvar1 + numofvar2 + 1));
  1092.                             return (1);
  1093.                         }
  1094.                     }
  1095.  
  1096.                     if (*term == entry)
  1097.                         found = 1;
  1098.  
  1099.                     term++;
  1100.                 }
  1101.  
  1102.                 if (!found)
  1103.                     *term = entry;
  1104.             }
  1105.  
  1106.             IncPointer(&res);
  1107.             IncPointer(&res);
  1108.         }
  1109.  
  1110.         numofvar = numofvar2;
  1111.         res      = res2;
  1112.         pos      = pos2;
  1113.     }
  1114.  
  1115.     if (!*termbuff)                      /* wenn termbuff leer ist, dann     */
  1116.         *termbuff = numofpins_Opt;       /* war A+/A in der Gleichung => VCC */
  1117.  
  1118.                                     /* untersuchen, ob der neue Prod.term */
  1119.                                     /* "termbuff" schon existiert         */
  1120.     pos   = equastart;
  1121.     found = 0;
  1122.  
  1123.     for(;;)
  1124.     {
  1125.         prodterm = pos;
  1126.  
  1127.         while ((!IsOR(*pos.Entry)) && (entry = *pos.Entry))
  1128.         {
  1129.             term  = termbuff;
  1130.             found = 0;
  1131.  
  1132.             while (*term)
  1133.             {
  1134.                 if (*term == entry)
  1135.                 {
  1136.                     found = 1;
  1137.                     break;
  1138.                 }
  1139.  
  1140.                 term++;
  1141.             }
  1142.  
  1143.             if (!found)
  1144.                 break;
  1145.  
  1146.             IncPointer(&pos);
  1147.  
  1148.             if (IsAND(*pos.Entry))  /* '*' überspringen, falls vorhanden */
  1149.                 IncPointer(&pos);
  1150.         }
  1151.  
  1152.                                             /* nächsten Prod.term suchen */
  1153.  
  1154.         while ((!IsOR(*pos.Entry)) && (*pos.Entry))
  1155.             IncPointer(&pos);
  1156.  
  1157.         nextprodterm = pos;
  1158.  
  1159.         if (found)
  1160.         {
  1161.             term = termbuff;
  1162.  
  1163.             while (*term)
  1164.             {
  1165.                 pos   = prodterm;
  1166.                 found = 0;
  1167.  
  1168.                 while ((!IsOR(*pos.Entry)) && (entry = *pos.Entry))
  1169.                 {
  1170.                     if (entry == *term)
  1171.                     {
  1172.                         found = 1;
  1173.                         break;
  1174.                     }
  1175.  
  1176.                     IncPointer(&pos);
  1177.  
  1178.                     if (IsAND(*pos.Entry))
  1179.                         IncPointer(&pos);
  1180.                 }
  1181.  
  1182.                 if (!found)
  1183.                     break;
  1184.  
  1185.                 term++;
  1186.             }
  1187.         }
  1188.  
  1189.         if (found)
  1190.             break;                          /* for-Schleife verlassen */
  1191.  
  1192.         pos = nextprodterm;
  1193.  
  1194.         if (!*pos.Entry)
  1195.             break;
  1196.  
  1197.         IncPointer(&pos);
  1198.     }
  1199.  
  1200.  
  1201.     if (!found)
  1202.     {                                   /* existiert Prod.term schon ?      */
  1203.                                         /* nein, dann an Gleichung anhängen */
  1204.  
  1205.         if (AddByte(equaend, (UBYTE)'+'))
  1206.         {
  1207.             FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  1208.             return(-1);
  1209.         }
  1210.  
  1211.         term = termbuff;
  1212.  
  1213.         while (*term)
  1214.         {
  1215.             if (AddByte(equaend, (UBYTE)*term))
  1216.             {
  1217.                 FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  1218.                 return(-1);
  1219.             }
  1220.  
  1221.             if (AddByte(equaend, (UBYTE)'*'))
  1222.             {
  1223.                 FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  1224.                 return(-1);
  1225.             }
  1226.  
  1227.             term++;
  1228.         }
  1229.  
  1230.         DecPointer(equaend);
  1231.  
  1232.         *equaend->Entry = 0;                        /* Endmarkierung */
  1233.  
  1234.         entry = *termbuff;
  1235.  
  1236.         FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  1237.  
  1238.         if (entry == numofpins_Opt)             /* wenn VCC gefunden wurde, */
  1239.             return(2);                          /* dann 2 zurückgeben       */
  1240.         else
  1241.             return(0);
  1242.     }
  1243.  
  1244.     FreeMem(termbuff, (long)(numofvar1+numofvar2+1));
  1245.  
  1246.     return(1);
  1247. }
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253. /******************************************************************************
  1254. ** SearchVar()
  1255. *******************************************************************************
  1256. ** input:   pos     pointer to start position
  1257. **          end     end position
  1258. **          var     pin name to be searched
  1259. **
  1260. ** output:      0:  name found
  1261. **             -1:  not found
  1262. **
  1263. ** remarks: This function does search the pin "var". Search from "pos" to
  1264. **          "end". Since this function is called very often registered
  1265. **          variables are necessary to be fast enough.
  1266. ******************************************************************************/
  1267.  
  1268. static int SearchVar(register struct ActBuffer *pos,
  1269.                      register struct ActBuffer end,
  1270.                      register UBYTE var)
  1271. {
  1272.  
  1273.     while (pos->Entry != end.Entry)
  1274.     {
  1275.         if (*pos->Entry == var)
  1276.             return(0);
  1277.  
  1278.         IncPointer(pos);
  1279.     }
  1280.  
  1281.     return(-1);
  1282. }
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288. /******************************************************************************
  1289. ** WriteNewSource()
  1290. *******************************************************************************
  1291. ** input:   buff        buffer where the equations are stored in
  1292. **          equastart   pointer to the start of the equation in the
  1293. **                      original source file
  1294. **          equend      pointer to the end of the equations in the
  1295. **                      original source file (DESCRIPTION)
  1296. **
  1297. ** output:      0:  o.k.
  1298. **             -1:  failed to write file
  1299. **
  1300. ** remarks: This function generates from the original source file and
  1301. **          from the optimized equations a new source file.
  1302. ******************************************************************************/
  1303.  
  1304. static int WriteNewSource(struct ActBuffer buff, UBYTE *equastart,
  1305.                           UBYTE *equaend)
  1306. {
  1307.     long    result;
  1308.     BPTR    fh;
  1309.     UBYTE   *filebuffer, *filebuffer2;
  1310.  
  1311.  
  1312.     if ((fh = Open(&path[0], (long)MODE_NEWFILE)))
  1313.     {
  1314.                                 /* write header of the new source file */
  1315.  
  1316.         result = Write(fh, (char *)fbuff, (long)(equastart-fbuff));
  1317.  
  1318.         if (result == -1L)
  1319.         {                       /* write error? */
  1320.             Close(fh);          /* then end     */
  1321.             return(-1);
  1322.         }
  1323.  
  1324.                                 /* write the equations */
  1325.         for (;;)
  1326.         {
  1327.             filebuffer = filebuffer2 = buff.Entry;
  1328.  
  1329.             while (filebuffer2 < buff.BuffEnd)  /* get size of buffer */
  1330.             {
  1331.                 if (!*filebuffer2)
  1332.                     break;
  1333.  
  1334.                 filebuffer2++;
  1335.             }
  1336.  
  1337.             result = Write(fh, (char *)filebuffer,
  1338.                            (long)(filebuffer2 - filebuffer));
  1339.  
  1340.             if (result == -1L)
  1341.             {                           /* write error? */
  1342.                 Close(fh);              /* then end     */
  1343.                 return(-1);
  1344.             }
  1345.  
  1346.             if (!buff.ThisBuff->Next)       /* are there some more buffers? */
  1347.                 break;                      /* no, then finish              */
  1348.  
  1349.             buff.ThisBuff = buff.ThisBuff->Next;
  1350.             buff.Entry    = (UBYTE *)(&buff.ThisBuff->Entries[0]);
  1351.             buff.BuffEnd  = (UBYTE *)buff.ThisBuff+(long)sizeof(struct Buffer);
  1352.         }
  1353.  
  1354.                                         /* write DESCRIPTION part */
  1355.  
  1356.         result = Write(fh, (char *)equaend, (long)(fbuff+fsize-equaend));
  1357.  
  1358.         if (result == -1L)
  1359.         {                               /* write error? */
  1360.             Close(fh);                  /* the cancel   */
  1361.             return(-1);
  1362.         }
  1363.  
  1364.         Close(fh);
  1365.     }
  1366.     else
  1367.         return(-1);
  1368.  
  1369.     return(0);
  1370. }
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376. /******************************************************************************
  1377. ** CopyEqua()
  1378. *******************************************************************************
  1379. ** input:       from    ActBuffer structure of source
  1380. **              to      ActBuffer structure of destination
  1381. **
  1382. ** output:      0:      o.k.
  1383. **            <>0:      failed (not enough free memory)
  1384. **
  1385. ** remarks: This function copies a equation from "from" to "to".
  1386. ******************************************************************************/
  1387.  
  1388. static int CopyEqua(struct ActBuffer from_buff, struct ActBuffer to_buff)
  1389. {
  1390.     register int    n;
  1391.  
  1392.     UBYTE    entry, pins[2*24];
  1393.  
  1394.     struct   ActBuffer  equastart, prodtermstart, pos;
  1395.  
  1396.  
  1397.  
  1398.     if (AddByte(&to_buff, (UBYTE)*from_buff.Entry)) /* copy output pin */
  1399.         return(-1);
  1400.  
  1401.     IncPointer(&from_buff);
  1402.  
  1403.     entry = *from_buff.Entry;
  1404.  
  1405.     if (entry == 'T' || entry == 'R' || entry == 'E' ||
  1406.         entry == 'C' || entry == 'S' || entry == 'P')
  1407.     {
  1408.  
  1409.         if (AddByte(&to_buff, (UBYTE)entry))        /* copy suffix T,R,E */
  1410.             return(-1);
  1411.  
  1412.         IncPointer(&from_buff);
  1413.     }
  1414.  
  1415.                                                     /* copy equation */
  1416.     equastart = prodtermstart = to_buff;
  1417.  
  1418.     for (;;)
  1419.     {
  1420.         for (n = 0; n < 2*24; pins[n++] = 0);       /* clear pins */
  1421.  
  1422.         for (;;)
  1423.         {
  1424.             entry = *from_buff.Entry;
  1425.  
  1426.             if (entry & NEGATION)
  1427.             {
  1428.                 if (pins[(entry & ~NEGATION) - 1])  /* A * /A? */
  1429.                 {
  1430.                     pos = prodtermstart;            /* yes, then skip */
  1431.                                                     /* this term      */
  1432.                     while (pos.Entry != to_buff.Entry)
  1433.                     {
  1434.                         *pos.Entry = EQUASKIP;
  1435.                         IncPointer(&pos);
  1436.                     }
  1437.  
  1438.                     to_buff = prodtermstart;
  1439.  
  1440.                     while ((!IsOR(*from_buff.Entry)) &&
  1441.                            (*from_buff.Entry != EQUAEND))
  1442.                         IncPointer(&from_buff);
  1443.  
  1444.                     DecPointer(&from_buff);
  1445.                 }
  1446.                 else
  1447.                 {
  1448.                     if (!pins[(entry & ~NEGATION) -1 + 24])
  1449.                     {                                /* is pin used several */
  1450.                                                      /* times within the    */
  1451.                                                      /* product term?       */
  1452.  
  1453.                                                      /* no, then copy */
  1454.                         pins[(entry&~NEGATION) - 1 + 24] = 1;
  1455.  
  1456.                         if (AddByte(&to_buff, (UBYTE)entry)) /* copy pin num */
  1457.                             return(-1);
  1458.                     }
  1459.                 }
  1460.             }
  1461.             else
  1462.             {
  1463.                 if (pins[entry - 1 + 24])          /* A * /A? */
  1464.                 {
  1465.  
  1466.                     pos = prodtermstart;           /* yes, then copy term */
  1467.  
  1468.                     while (pos.Entry != to_buff.Entry)
  1469.                     {                              /* erase and skip */
  1470.                         *pos.Entry = EQUASKIP;
  1471.                         IncPointer(&pos);
  1472.                     }
  1473.  
  1474.                     to_buff = prodtermstart;
  1475.  
  1476.                     while ((!IsOR(*from_buff.Entry)) &&
  1477.                            (*from_buff.Entry != EQUAEND))
  1478.                         IncPointer(&from_buff);
  1479.  
  1480.                     DecPointer(&from_buff);
  1481.                 }
  1482.                 else
  1483.                 {
  1484.  
  1485.                     if (!pins[entry-1])         /* is pin name used several */
  1486.                     {                           /* times?                   */
  1487.                         pins[entry - 1] = 1;    /* no, then copy            */
  1488.  
  1489.                         if (AddByte(&to_buff, (UBYTE)entry)) /* copy pin num */
  1490.                             return(-1);
  1491.                     }
  1492.                 }
  1493.             }
  1494.  
  1495.  
  1496.             IncPointer(&from_buff);         /* pointer to operation or */
  1497.                                             /* EQUAEND                 */
  1498.             entry = *from_buff.Entry;
  1499.  
  1500.             if (entry == EQUAEND)           /* end reached? */
  1501.             {
  1502.                 DecPointer(&to_buff);       /* yes, then we are ready */
  1503.  
  1504.                 if (!(IsOR(*to_buff.Entry) || IsAND(*to_buff.Entry) ))
  1505.                     IncPointer(&to_buff);   /* remove +, * at the end */
  1506.  
  1507.                 if (AddByte(&to_buff, (UBYTE)EQUAEND))  /* send end mark */
  1508.                     return(-1);
  1509.  
  1510.                 return(0);
  1511.             }
  1512.  
  1513.             if (to_buff.Entry != equastart.Entry) /* still at the beginning? */
  1514.             {
  1515.                 DecPointer(&to_buff);
  1516.  
  1517.                 if (!IsOR(*to_buff.Entry))
  1518.                 {
  1519.                     if (!IsAND(*to_buff.Entry))
  1520.                     {
  1521.                         IncPointer(&to_buff);
  1522.  
  1523.                         if (AddByte(&to_buff, (UBYTE)entry))
  1524.                             return(-1);
  1525.                     }
  1526.                     else
  1527.                     {
  1528.                         if (IsOR(entry))
  1529.                             *to_buff.Entry = '+';
  1530.  
  1531.                         IncPointer(&to_buff);
  1532.                     }
  1533.                 }
  1534.                 else
  1535.                     IncPointer(&to_buff);
  1536.             }
  1537.  
  1538.  
  1539.             if (IsOR(entry))                /* end of product term reached? */
  1540.                 break;                      /* then leave loop              */
  1541.  
  1542.  
  1543.             IncPointer(&from_buff);         /* set pointer to pin name */
  1544.         }
  1545.  
  1546.         prodtermstart = to_buff;
  1547.  
  1548.         IncPointer(&from_buff);
  1549.     }
  1550. }
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556. /******************************************************************************
  1557. ** PrintEqua()
  1558. *******************************************************************************
  1559. ** input:   buff      ActBuffer structure of an equation
  1560. **          filebuff  NULL: prints an equation into the window
  1561. **                    else: put the optimized equations in a buffer which is
  1562. **                          then used to generate the source file
  1563. **
  1564. ** output:    0:    ok
  1565. **          <>0:    failed (not enough free memory)
  1566. **
  1567. ** remarks: This function does print the coded equation which ends with
  1568. **          ENDEQUAS or ENDEQUA.
  1569. ******************************************************************************/
  1570.  
  1571. static int PrintEqua(struct ActBuffer buff, struct ActBuffer *filebuff)
  1572. {
  1573.     char    estrng[SIZE_OF_EQUASTRING];
  1574.     int     n, entry, xoffset, notready;
  1575.  
  1576.  
  1577.     num_of_ORs = num_of_ANDs = 0;
  1578.     estrng[0] = 0;                                /* clear string */
  1579.  
  1580.     entry = *buff.Entry;
  1581.  
  1582.     if (entry & NEGATION)
  1583.     {
  1584.         strcat((char *)&estrng[0], "/");
  1585.         entry = entry & (~NEGATION);
  1586.     }
  1587.  
  1588.     if (IsNEG(PinNamesOpt[entry-1][0]))         /* output */
  1589.         strcat((char *)&estrng[0], (char *)&PinNamesOpt[entry-1][1]);
  1590.     else
  1591.         strcat((char *)&estrng[0], (char *)&PinNamesOpt[entry-1][0]);
  1592.  
  1593.     entry = GetNext(&buff);
  1594.  
  1595.     if (entry == 'T')
  1596.     {
  1597.         entry = GetNext(&buff);
  1598.         strcat ((char *)&estrng[0], ".T");          /* print suffix */
  1599.     }
  1600.     else
  1601.         if (entry == 'E')
  1602.         {
  1603.             entry = GetNext(&buff);
  1604.             strcat ((char *)&estrng[0], ".E");
  1605.         }
  1606.         else
  1607.             if (entry == 'R')
  1608.             {
  1609.                 entry = GetNext(&buff);
  1610.                 strcat ((char *)&estrng[0], ".R");
  1611.             }
  1612.             else
  1613.                 if (entry == 'C')
  1614.                 {
  1615.                     entry = GetNext(&buff);
  1616.                     strcat ((char *)&estrng[0], ".CLK");
  1617.                 }
  1618.                 else
  1619.                     if (entry == 'S')
  1620.                     {
  1621.                         entry = GetNext(&buff);
  1622.                         strcat ((char *)&estrng[0], ".ARST");
  1623.                     }
  1624.                     else
  1625.                         if (entry == 'P')
  1626.                         {
  1627.                             entry = GetNext(&buff);
  1628.                             strcat ((char *)&estrng[0], ".APRST");
  1629.                         }
  1630.  
  1631.  
  1632.  
  1633.     strcat ((char *)&estrng[0], " = ");           /* add '=' */
  1634.  
  1635.     xoffset = strlen(&estrng[0]);                 /* save length of string */
  1636.  
  1637.     notready = TRUE;
  1638.  
  1639.     while (notready)
  1640.     {
  1641.         while (strlen(&estrng[0]) < (SIZE_OF_EQUASTRING - 15))
  1642.         {
  1643.  
  1644.             if (entry & NEGATION)
  1645.             {
  1646.                 strcat((char *)&estrng[0], "/");
  1647.                 entry = entry & (~NEGATION);
  1648.             }
  1649.  
  1650.             if (IsNEG(PinNamesOpt[entry-1][0]))               /* get pin name */
  1651.                 strcat ((char *)&estrng[0], (char *)&PinNamesOpt[entry-1][1]);
  1652.             else
  1653.                 strcat ((char *)&estrng[0], (char *)&PinNamesOpt[entry-1][0]);
  1654.  
  1655.             if ((entry = GetNext(&buff)) == EQUAEND)
  1656.             {
  1657.                 notready = FALSE;
  1658.                 break;
  1659.             }
  1660.  
  1661.             if (IsOR(entry))
  1662.             {
  1663.                 strcat((char *)&estrng[0], " + ");      /* get op. */
  1664.                 num_of_ORs++;
  1665.             }
  1666.             else
  1667.             {
  1668.                 strcat((char *)&estrng[0], "*");
  1669.                 num_of_ANDs++;
  1670.             }
  1671.  
  1672.             if ((entry = GetNext(&buff)) == EQUAEND)
  1673.             {
  1674.                 notready = FALSE;
  1675.                 break;
  1676.             }
  1677.         }
  1678.  
  1679.         if (!filebuff)
  1680.             PrintOptText((UBYTE *)&estrng[0]);        /* print one line */
  1681.         else
  1682.         {
  1683.             n = 0;                                    /* put string into list */
  1684.  
  1685.             while (estrng[n])
  1686.             {
  1687.                 if (AddByte(filebuff, (UBYTE)estrng[n]))
  1688.                     return(-1);
  1689.  
  1690.                 n++;
  1691.             }
  1692.  
  1693.             if (AddByte(filebuff, (UBYTE)0x0A))        /* add a return */
  1694.                 return(-1);
  1695.         }
  1696.  
  1697.         for (n=0; n<xoffset; n++)               /* add spaces ' ' up to */
  1698.             estrng[n] = ' ';                    /* xoffset              */
  1699.  
  1700.         estrng[xoffset] = 0;                    /* clear the rest of string */
  1701.     }
  1702.  
  1703.     if (filebuff)                               /* make file list?         */
  1704.         if (AddByte(filebuff, (UBYTE)0x0A))     /* add a return at the end */
  1705.             return(-1);                         /* of an equation          */
  1706.  
  1707.  
  1708.     return(0);
  1709. }
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715. /******************************************************************************
  1716. ** GetNext()
  1717. *******************************************************************************
  1718. ** input:   buff    pointer to ActBuffer structure
  1719. **
  1720. ** output:          next entry which is no EQUASKIP
  1721. **
  1722. ** remarks: gets the next entry from the buffer "buff" which is no EQUASKIP
  1723. ******************************************************************************/
  1724.  
  1725. static int GetNext(struct ActBuffer *buff)
  1726. {
  1727.  
  1728.     do
  1729.         IncPointer(buff);
  1730.     while (*buff->Entry == EQUASKIP);
  1731.  
  1732.     return(*buff->Entry);
  1733. }
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739. /******************************************************************************
  1740. ** GetNextEqua()
  1741. *******************************************************************************
  1742. ** input:   buff    pointer to the ActBuffer structure
  1743. **
  1744. ** output:  FALSE:  there are no more equations
  1745. **          TRUE:   one equation found
  1746. **          buff:   actuell pointer to the equation
  1747. **
  1748. ** remarks: searchs for the next coded equation
  1749. ******************************************************************************/
  1750.  
  1751. static int GetNextEqua(struct ActBuffer *buff)
  1752. {
  1753.  
  1754.     while (*buff->Entry != EQUAEND)
  1755.         IncPointer(buff);
  1756.  
  1757.     IncPointer(buff);
  1758.  
  1759.     if (*buff->Entry == EQUASEND)
  1760.         return(FALSE);
  1761.     else
  1762.         return(TRUE);
  1763. }
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769. /******************************************************************************
  1770. ** PrintOptText()
  1771. *******************************************************************************
  1772. ** input:   txt     text to be displayed
  1773. **
  1774. **          global: LV_opt is the pointer to the listview object
  1775. **
  1776. ** output:  none
  1777. **
  1778. ** remarks: This function does add a string to the optimizer's listview.
  1779. ******************************************************************************/
  1780.  
  1781. static void PrintOptText(UBYTE *txt)
  1782. {
  1783.  
  1784.     DoMethod(LV_opt, MUIM_List_InsertSingle,  /* add line to  */
  1785.              txt, MUIV_List_Insert_Bottom);   /* the listview */
  1786.  
  1787. }
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  1793. /******************************************************************************
  1794. ** TranslateEqua()
  1795. *******************************************************************************
  1796. ** input:   buff    pointer to the equations
  1797. **
  1798. ** output:    0: ok
  1799. **          <>0: failed (not enough free memory)
  1800. **
  1801. ** remarks: This function translates all Boolean equations from the ASCII
  1802. **          form into a coded form. So it's easier to deal with the equations.
  1803. **          Code: pinname   ->  pin number
  1804. **                /pinname  ->  pin number and bit 7 set
  1805. **                T,R,E,+,* ->  T,R,E,+,*
  1806. **                CLK, ARST, APRST -> C, S, P
  1807. **                CR,LF,'.','=' are skiped
  1808. ******************************************************************************/
  1809.  
  1810. static int TranslateEqua(struct ActBuffer *buff)
  1811. {
  1812.     int     n;
  1813.     UBYTE   chr, entry;
  1814.     char    suffix_strn[MAX_SUFFIX_SIZE];
  1815.  
  1816.  
  1817.  
  1818.     if (GetNextChar())
  1819.     {                                   /* end of file?  */
  1820.         AsmError(2, 0);                 /* yes, then end */
  1821.         return(-1);
  1822.     }
  1823.                                         /* is there an equation? */
  1824.  
  1825.     if (!strncmp((char *)actptr, "DESCRIPTION", (size_t)11))
  1826.     {
  1827.         AsmError(33, 0);                /* no, then error */
  1828.         return(-1);
  1829.     }
  1830.  
  1831.  
  1832.     for (;;)
  1833.     {
  1834.         IsPinName((UBYTE *)&PinNamesOpt[0], numofpins_Opt);
  1835.  
  1836.         if (!actPin.p_Pin)
  1837.         {                               /* pin name?      */
  1838.             AsmError(11, 0);            /* no, then error */
  1839.             return(-1);
  1840.         }
  1841.  
  1842.         if (actPin.p_Neg)
  1843.             entry = actPin.p_Pin | NEGATION;
  1844.         else
  1845.             entry = actPin.p_Pin;
  1846.  
  1847.         if (AddByte(buff, (UBYTE)entry))
  1848.             return(-1);
  1849.  
  1850.  
  1851.         if (*actptr == '.')
  1852.         {                               /* get suffix */
  1853.  
  1854.             actptr++;
  1855.  
  1856.             n = 0;
  1857.  
  1858.             while (isalpha(*actptr))
  1859.             {                                   /* copy suffix string into */
  1860.                 if (n < MAX_SUFFIX_SIZE)        /* suffix array            */
  1861.                     suffix_strn[n++] = *actptr++;
  1862.                 else
  1863.                 {                               /* string too long, then */
  1864.                     AsmError(13, 0);            /* unknown suffix        */
  1865.                     return(-1);
  1866.                 }
  1867.             }
  1868.  
  1869.             suffix_strn[n] = 0;                    /* mark end of string */
  1870.  
  1871.             if (!strcmp(&suffix_strn[0], "T"))
  1872.                 chr = 'T';
  1873.             else
  1874.                 if (!strcmp(&suffix_strn[0], "R"))
  1875.                     chr = 'R';
  1876.                 else
  1877.                     if (!strcmp(&suffix_strn[0], "E"))
  1878.                         chr = 'E';
  1879.                     else
  1880.                         if (!strcmp(&suffix_strn[0], "CLK"))
  1881.                             chr = 'C';
  1882.                         else
  1883.                             if (!strcmp(&suffix_strn[0], "ARST"))
  1884.                                 chr = 'S';
  1885.                             else
  1886.                                 if (!strcmp(&suffix_strn[0], "APRST"))
  1887.                                     chr = 'P';
  1888.                                 else
  1889.                                 {
  1890.                                     AsmError(13, 0);
  1891.                                     return(-1);
  1892.                                 }
  1893.  
  1894.             if (AddByte(buff, (UBYTE)chr))            /* add code of suffix */
  1895.                 return(-1);
  1896.         }
  1897.  
  1898.  
  1899.         if (GetNextChar())
  1900.         {                                   /* end of file? */
  1901.             AsmError(2, 0);
  1902.             return(-1);
  1903.         }
  1904.  
  1905.         if (*actptr != '=')
  1906.         {                                   /* '='?           */
  1907.             AsmError(14, 0);                /* no, then error */
  1908.             return(-1);
  1909.         }
  1910.  
  1911.         actptr++;
  1912.  
  1913.         if (GetNextChar())
  1914.         {                                   /* end of file?    */
  1915.             AsmError(2, 0);                 /* yes, then error */
  1916.             return(-1);
  1917.         }
  1918.  
  1919.  
  1920.         for (;;)
  1921.         {
  1922.             IsPinName((UBYTE *)&PinNamesOpt[0], numofpins_Opt);
  1923.  
  1924.             if (!actPin.p_Pin)
  1925.             {                               /* pin name?      */
  1926.                 AsmError(11, 0);            /* no, then error */
  1927.                 return(-1);
  1928.             }
  1929.  
  1930.             if (actPin.p_Neg)
  1931.                 entry = actPin.p_Pin | NEGATION;
  1932.             else
  1933.                 entry = actPin.p_Pin;
  1934.  
  1935.             if (AddByte(buff, (UBYTE)entry))
  1936.                 return(-1);
  1937.  
  1938.             if (GetNextChar())
  1939.             {                               /* end of file?    */
  1940.                 AsmError(2, 0);             /* yes, then error */
  1941.                 return(-1);
  1942.             }
  1943.  
  1944.             if (!( IsOR(*actptr) || IsAND(*actptr) ))
  1945.             {                                           /* OR or AND? */
  1946.                 if (strncmp((char *)actptr, "DESCRIPTION", (size_t)11))
  1947.                 {                                       /* DESCRIPTION? */
  1948.                     if (AddByte(buff, (UBYTE)EQUAEND))  /*set mark for the   */
  1949.                         return(-1);                     /*end of the equation*/
  1950.  
  1951.                     break;                      /* no OR nor AND, then end */
  1952.                 }
  1953.                 else
  1954.                 {
  1955.                     if (AddByte(buff, (UBYTE)EQUAEND)) /* set mark for the    */
  1956.                         return(-1);                    /* end of the equation */
  1957.  
  1958.                     if (AddByte(buff, (UBYTE)EQUASEND))
  1959.                         return(-1);         /* set mark for the end of all   */
  1960.                                             /* equations (after this mark    */
  1961.                                             /* DESCRIPTION follows). Now     */
  1962.                                             /* all equations are translated. */
  1963.                     return(0);
  1964.                 }
  1965.             }
  1966.  
  1967.             if (AddByte(buff, (UBYTE)*actptr))
  1968.                 return(-1);
  1969.  
  1970.             actptr++;
  1971.  
  1972.             if (GetNextChar())
  1973.             {                               /* unexpected end of file? */
  1974.                 AsmError(2, 0);
  1975.                 return(-1);
  1976.             }
  1977.         }
  1978.     }
  1979. }
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985. /* EOF */
  1986.