home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mass61.zip / mass.zip / masm61 / DISK3 / SAMPLES / DEMOS / MATHDEMO.C$ / MATHDEMO
Text File  |  1992-11-12  |  15KB  |  387 lines

  1. /* MATHDEMO.C - Creates a simple on-screen calculator with functions for
  2.  * basic integer arithmetic and for solving for the roots of a quadratic
  3.  * equation. MATHDEMO invokes procedures that illustrate assembly-language
  4.  * instructions related to mathematics, including those specific to the
  5.  * 8087 family of coprocessors.
  6.  *
  7.  * MATHDEMO.EXE is built from the following files:
  8.  *    MATHDEMO.C - Main program
  9.  *    MATH.ASM   - Assembly procedures for MATHDEMO
  10.  *    COMMON.ASM - Assembly procedures shared by other example programs
  11.  *    DEMO.INC   - Assembly include file with macros and structure declarations
  12.  *    DEMO.H     - C include file with prototypes and structure declarations
  13.  *
  14.  * Procedures:  AddLong       MulLong      DivLong     Quadratic
  15.  *              SubLong       ImulLong     IdivLong
  16.  */
  17.  
  18. #include "demo.h"
  19. #include <dos.h>
  20. #include <conio.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23.  
  24. /* Function prototypes */
  25. void display_calc( void );
  26. void display_help( void );
  27. void press( void );
  28. void push( int sign );
  29.  
  30. /* Global variables */
  31. long s1, s2, s3;                /* Stack values: 1st, 2nd, 3rd      */
  32. char entry[11];                 /* Entry window string              */
  33. int  col;                       /* Current display column for entry */
  34.  
  35. main()
  36. {
  37.     int ch, err;                        /* Keyboard character, return val  */
  38.     static int sign, mode;              /* Sign flag, signed/unsigned flag */
  39.     static float root1, root2;          /* Roots of quadratic equation     */
  40.     static short quotient, remainder;   /* Results of division             */
  41.     static long *product, result;
  42.     static char *rmsg[2] = { "Complex", "roots" };
  43.     static char *dmsg[2] = { "Division by", "Zero" };
  44.     static char *highmsg = { "high:" };
  45.     static char *lowmsg  = { "low:" };
  46.  
  47.     GetVidConfig();
  48.     display_calc();
  49.     StrWrite( 9, 14, "+" );
  50.     col = 20;
  51.     do
  52.     {
  53.         SetCurPos( 9, col );
  54.         ch = getch();
  55.         switch( (ch = toupper( ch )) )
  56.         {
  57.             /* Display number in entry window. */
  58.             case '0':
  59.             case '1':
  60.             case '2':
  61.             case '3':
  62.             case '4':
  63.             case '5':
  64.             case '6':
  65.             case '7':
  66.             case '8':
  67.             case '9':
  68.                 putch( (char) ch );
  69.                 entry[col - 20] = (char) ch;
  70.                 entry[++col - 20] = 0;
  71.                 if( col == 30 )
  72.                     col--;
  73.                 break;
  74.  
  75.             /* Toggle between signed and unsigned arithmetic modes. */
  76.             case 'M':
  77.                 if( mode )
  78.                 {
  79.                     mode = 0;                   /* For signed mode,   */
  80.                     StrWrite( 14, 57, "  (" );  /*   toggle flag off  */
  81.                     StrWrite( 9, 14, "+" );     /*   and restore sign */
  82.                 }
  83.                 else
  84.                 {
  85.                     mode++;                     /* For unsigned mode, */
  86.                     StrWrite( 14, 57, "(un" );  /*   toggle flag on   */
  87.                     StrWrite(  9, 14, " " );    /*   and blank sign   */
  88.                 }
  89.                 sign = 0;
  90.                 break;
  91.  
  92.             /* Solve for x in quadratic equation s3*x*x + s2*x + s3 = 0. */
  93.             case 'Q':
  94.                 push( sign );
  95.                 err = Quadratic( (float)s3, (float)s2, (float)s1,
  96.                                   &root1, &root2 );
  97.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window   */
  98.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window  */
  99.                 if( err < 2 )
  100.                 {
  101.                     SetCurPos( 9, 50 );
  102.                     printf( "%16.3f", root1 );          /* Display 1st root */
  103.                     if( !err )
  104.                     {
  105.                         SetCurPos( 10, 50 );
  106.                         printf( "%16.3f", root2 );      /* Display 2nd root */
  107.                     }
  108.                 }
  109.                 if( err == 2)
  110.                 {
  111.                     StrWrite(  9, 50, rmsg[0] );   /* Display "Complex  */
  112.                     StrWrite( 10, 50, rmsg[1] );   /*   roots"          */
  113.                 }
  114.                 break;
  115.  
  116.             /* Change sign. */
  117.             case 'S':
  118.                 if( !mode )             /* Allow sign changes only */
  119.                 {                       /*   in signed mode        */
  120.                     if( sign )
  121.                     {
  122.                         StrWrite( 9, 14, "+" );
  123.                         sign = 0;
  124.                     }
  125.                     else
  126.                     {
  127.                         StrWrite( 9, 14, "-" );
  128.                         sign++;
  129.                     }
  130.                 }
  131.                 break;
  132.  
  133.             /* Clear stack, reinitialize variables. */
  134.             case 'C':
  135.                 s3 = s2 = s1 = 0;
  136.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window  */
  137.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window */
  138.                 entry[0] = 0;
  139.                 col = 20;
  140.                 break;
  141.  
  142.             /* Push values down stack when ENTER key pressed. */
  143.             case CR:
  144.                 push( sign );
  145.                 break;
  146.  
  147.             /* Display help screen. */
  148.             case '?':
  149.             case 'H':
  150.                 display_help();                 /* Display help         */
  151.                 display_calc();                 /* Redisplay calculator */
  152.                 StrWrite( 9, 20, entry );       /*   and entry number   */
  153.                 if( mode )
  154.                 {
  155.                     StrWrite( 14, 57, "(un" );  /* Make "unsigned"      */
  156.                     StrWrite(  9, 14, " " );    /*   and blank sign     */
  157.                 }
  158.                 else
  159.                 {
  160.                     if( sign )
  161.                         StrWrite( 9, 14, "-" );
  162.                     else
  163.                         StrWrite( 9, 14, "+" );
  164.                 }
  165.                 break;
  166.  
  167.             /* Add or subtract s1 and s2. */
  168.             case '+':
  169.             case '-':
  170.                 push( sign );
  171.                 if( (char) ch == '+' )
  172.                     s1 = AddLong( s2, s1 );
  173.                 else
  174.                     s1 = SubLong( s2, s1 );
  175.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window   */
  176.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window  */
  177.                 SetCurPos( 9, 56 );
  178.                 if( mode )
  179.                     printf( "%lu", s1 );        /* Display unsigned or  */
  180.                 else
  181.                     printf( "%li", s1 );        /*   signed result      */
  182.                 break;
  183.  
  184.             /* Multiply s1 and s2. */
  185.             case '*':
  186.                 push( sign );
  187.                 if( mode )
  188.                     product = MulLong(  s2, s1 );
  189.                 else
  190.                     s1      = ImulLong( s2, s1 );
  191.                 ClearBox( 7, 9, 15, 9, 29 );    /* Clear entry window   */
  192.                 ClearBox( 7, 9, 49, 10, 66 );   /* Clear result window  */
  193.                 if( mode )
  194.                 {
  195.                     StrWrite(  9, 50, highmsg );
  196.                     StrWrite( 10, 50, lowmsg );
  197.                     SetCurPos( 9, 56 );
  198.                     printf( "%lu", *++product ); /* Display high and low   */
  199.                     SetCurPos( 10, 56 );         /*   double-word of       */
  200.                     printf( "%lu", *--product ); /*   unsigned product     */
  201.                     s1 = *product;               /* Copy low word to stack */
  202.                 }
  203.                 else
  204.                 {
  205.                     SetCurPos( 9, 56 );
  206.                     printf( "%li", s1 );        /* Display signed product  */
  207.                 }
  208.                 break;
  209.  
  210.             /* Divide s2 by s1. */
  211.             case '/':
  212.                 push( sign );
  213.                 if ( s1 == 0 )
  214.                 {
  215.                     StrWrite(  9, 50, dmsg[0] );   /* Display "Division by */
  216.                     StrWrite( 10, 50, dmsg[1] );   /*   zero"              */
  217.                 }
  218.                 else
  219.                 {
  220.                     if( mode )
  221.                         quotient = DivLong(  s2, (int) s1, &remainder );
  222.                     else
  223.                         quotient = IdivLong( s2, (int) s1, &remainder );
  224.                     ClearBox( 7, 9, 15, 9, 29 );   /* Clear entry          */
  225.                     ClearBox( 7, 9, 49, 10, 66 );  /* Clear result         */
  226.                     if( abs( (int) remainder ) >= (abs( (int) s1 ) >> 1) )
  227.                     {
  228.                         if( quotient >= 0 )        /* Round up if          */
  229.                             quotient++;            /*   remainder > s1/2   */
  230.                         else
  231.                             quotient--;
  232.                     }
  233.                     SetCurPos( 9, 56 );
  234.                     if( mode )
  235.                         printf( "%u", quotient );   /* Display result */
  236.                     else
  237.                         printf( "%i", quotient );
  238.                     s1 = (long) quotient;           /* Copy quotient to stack */
  239.                 }
  240.                 break;
  241.  
  242.         }
  243.     } while( ch != ESCAPE );
  244.  
  245.     clear_scrn( 7, 0, 24 );             /* Clear screen before exit   */
  246.     SetCurPos( 23, 0 );                 /*   and set cursor to bottom */
  247.     return( 0 );
  248. }
  249.  
  250.  
  251. /* display_calc - Clears screen and displays calculator.
  252.  *
  253.  * Params:  None
  254.  */
  255.  
  256. void display_calc( void )
  257. {
  258.     static char *calculator[19] =
  259.     {
  260.    "                  ***   MATH Demonstration Program  ***",
  261.    "",
  262.    "",
  263.    "┌─ Integer Calculator ───────────────────────────────────────────────────┐",
  264.    "│                                                                        │",
  265.    "│         ┌────────────────┐                 ┌──────────────────┐        │",
  266.    "│         │                │                 │                  │        │",
  267.    "│         └────────────────┘                 │                  │        │",
  268.    "│                      entry                 └──────────────────┘        │",
  269.    "│                                                          result        │",
  270.    "│         7  8  9      +   -                 ? = Help                    │",
  271.    "│                                            M = Mode   (signed)         │",
  272.    "│         4  5  6      *   /                 S = Change sign             │",
  273.    "│                                            Q = Solve quadratic         │",
  274.    "│         1  2  3      ─┘ Enter             C = Clear all               │",
  275.    "│                                                                        │",
  276.    "│            0                             Esc = Quit                    │",
  277.    "│                                                                        │",
  278.    "└────────────────────────────────────────────────────────────────────────┘"
  279.     };
  280.     int i;
  281.  
  282.     clear_scrn( 7, 0, 24 );
  283.     if( vconfig.display )
  284.         ClearBox( 31, 6, 2, 21, 77 );
  285.     else
  286.         ClearBox( 15, 6, 2, 21, 77 );
  287.     ClearBox( 7, 9, 14, 9, 29 );                /* Clear entry window  */
  288.     ClearBox( 7, 9, 49, 10, 66 );               /* Clear result window */
  289.     for( i = 0; i < 19; i++)                    /* Display calculator  */
  290.         StrWrite( i + 3, 3, calculator[i] );
  291. }
  292.  
  293.  
  294.  
  295. /* display_help - Clears screen and displays help text.
  296.  *
  297.  * Params:  None
  298.  */
  299.  
  300. void display_help( void )
  301. {
  302.     static char *help_msg[24] =
  303.     {
  304.         "The Integer Calculator works somewhat like an RPN hand "
  305.         "calculator.  Type the", "first integer, press Enter (─┘), type the "
  306.         "second integer, and press the", "desired operator key.  The answer "
  307.         "appears in the result window.",
  308.         "",
  309.         "To keep things simple, the Integer Calculator handles only long or "
  310.         "short", "integers -- no floating point numbers allowed.  Unsigned "
  311.         "numbers can range", "from 0 to 4,294,967,295; signed numbers from "
  312.         "-2,147,483,648 to 2,147,483,647.", "There's one exception to "
  313.         "this:  when dividing two numbers, the divisor must", "be a short "
  314.         "integer from 0 to 65,535 for unsigned division, or from -32,768",
  315.         "to 32,767 for signed division.",
  316.         "",
  317.         "Press the M key to toggle between signed and unsigned arithmetic.  " \
  318.         "Press the", "S key to change the sign of the number in the entry "
  319.         "window.  You'll notice", "the Calculator allows a change of sign "
  320.         "only in \"signed\" mode.",
  321.         "",
  322.         "The Calculator uses coprocessor instructions (either real or "
  323.         "simulated) to", "solve for the roots of a quadratic equation in "
  324.         "the form",
  325.         "",
  326.         "                     A*x*x + B*x + C = 0",
  327.         "",
  328.         "Enter the three equation constants A, B, and C in order, then "
  329.         "press Q.  The", "roots, if they exist, appear in the result "
  330.         "window.  If the equation has only", "one root, then only a single "
  331.         "number is displayed.  For example, try entering", "3, 7, and 2 "
  332.         "for A, B, and C."
  333.     };
  334.     int i;
  335.  
  336.     clear_scrn( 7, 0, 24 );
  337.     for( i = 0; i < 24; i++)
  338.         StrWrite( i, 0, help_msg[i] );
  339.     press();
  340. }
  341.  
  342.  
  343. /* push - Pushes values down one stack position:  s3 becomes s2,
  344.  * s2 becomes s1, and s1 becomes the value in the entry window.
  345.  *
  346.  * Params:  sign - Current sign status (0 = positive, 1 = negative)
  347.  */
  348.  
  349. void push( int sign )
  350. {
  351.     unsigned long place;
  352.  
  353.     s3    = s2;
  354.     s2    = s1;
  355.     s1    = 0;
  356.     place = 1;
  357.     if( entry[col - 20] )
  358.     {
  359.         s1    = (long) (entry[col - 20] - '0');
  360.         place = 10;
  361.     }
  362.     while( col > 20 )
  363.     {
  364.         s1    += place * (long) (entry[--col - 20] - '0');
  365.         place *= 10;
  366.     }
  367.     if( sign )
  368.         s1 = -s1;
  369.     ClearBox( 7, 9, 15, 9, 29 );        /* Clear entry window        */
  370.     entry[0] = 0;                       /* Reinitialize entry string */
  371.     col      = 20;                      /* Reset column count        */
  372. }
  373.  
  374.  
  375. /* press - Prompt for keyboard signal to continue.
  376.  *
  377.  * Params:  None
  378.  */
  379.  
  380. void press( void )
  381. {
  382.     SetCurPos( 24, 49 );
  383.     printf( ". . . press a key to continue" );
  384.     SetCurPos( 24, 47 );
  385.     getch();
  386. }
  387.