home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1989 / 02 / bowling.asc next >
Text File  |  1989-01-04  |  12KB  |  483 lines

  1. _Real-Time Modleing with MS-DOS_
  2. by David Bowling
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7.   #include <dos.h>
  8.  
  9.   #define  TRUE   -1
  10.   #define  FALSE   0
  11.  
  12.   void user_defined_background_task();
  13.   void set_up_user_background_task();
  14.   void set_down_user_background_task();
  15.   void set_up_user_real_time_task();
  16.   void set_down_user_real_time_task();
  17.   void set_up_real_time_task();
  18.   void set_down_real_time_task();
  19.  
  20.   int not_done = TRUE;
  21.   int over_run = FALSE;
  22.  
  23.   main(){
  24.     set_up_user_real_time_task();     /*initialization section*/
  25.     set_up_real_time_task();
  26.     set_up_user_background_task();
  27.  
  28.     while( not_done && ! over_run){    /*background task loop*/  
  29.     user_defined_background_task();
  30.     }
  31.  
  32.     set_down_real_time_task();         /*termination section*/   
  33.     set_down_user_background_task();
  34.     set_down_user_real_time_task();
  35.  
  36.     if( over_run )
  37.       printf("Error exit, frame over run\n");
  38.    }
  39.  
  40.  
  41.  
  42.  
  43.  
  44. [LISTING TWO]
  45.  
  46.   void interrupt real_time_task();
  47.   void interrupt (*old_clock_func)();
  48.   void set_timer();
  49.   int user_define_divisor = 1; /*initialize in case user forgets*/
  50.  
  51.   void set_up_real_time_task()
  52.   {
  53.     void interrupt (*getvect())();
  54.  
  55.     old_clock_func = getvect( 0x08 );/*save original clock vector*/
  56.      setvect( 0x50, old_clock_func );/*store in unused location*/
  57.      setvect( 0x08, real_time_task ); /*overwrite with real-time*/
  58.     set_timer( user_define_divisor ); /*set system timer*/
  59.   }
  60.  
  61.   void set_down_real_time_task(){
  62.     setvect( 0x08, old_clock_func ); /*restore clock vector*/
  63.     set_timer( 1 );                  /*reset system timer*/
  64.   }
  65.  
  66.  
  67. [LISTING THREE]
  68.  
  69.  
  70.   int running = FALSE;
  71.   int inter_count = 0;
  72.  
  73.   void interrupt real_time_task(){
  74.     enable();
  75.  
  76.     if( !running && !over_run ){
  77.       running = TRUE;
  78.       user_defined_real_time_task(); /*real-time function*/
  79.     }else{
  80.       over_run = TRUE;
  81.     };
  82.  
  83.     if( inter_count == user_define_divisor ){
  84.       geninterrupt( 0x50 );     /*call system clock*/
  85.       inter_count = 0;
  86.     }else{
  87.       outport( 0x20, 0x20 );    /*8259 end of interrupt routine*/
  88.       inter_count += 1;
  89.     };
  90.  
  91.     running = FALSE;
  92.   }
  93.  
  94.  
  95.  
  96.  
  97.  
  98. [LISTING FOUR]
  99.  
  100.   void set_timer( divisor )
  101.     int divisor;
  102.   {
  103.     int cnt;
  104.     int lo, hi;
  105.  
  106.     cnt = 65536 / divisor;
  107.  
  108.     lo = cnt % 256;
  109.     hi = cnt / 256;
  110.  
  111.     outportb( 0x43, 0x36 );
  112.     outportb( 0x40, lo );    /*write tic counter*/
  113.     outportb( 0x40, hi );
  114.   }
  115.  
  116.  
  117. [LISTING FIVE] 
  118.  
  119.   int i = 0;  /* DATAPOOL */
  120.  
  121.   user_defined_background_task(){
  122.     printf("i = %d\n", i );
  123.   }
  124.  
  125.   user_defined_real_time_function(){
  126.     i += 1;
  127.   }
  128.  
  129.  
  130.  
  131.  
  132. [LISTING SIX]
  133.  
  134.       union{
  135.        char coprocessor_state[94];
  136.        int control_word;
  137.      }float_save;
  138.   
  139.       /* save coprocessor state */
  140.       asm   fsave float_save.coprocessor_state
  141.       asm   fldcw float_save.control_word
  142.                .
  143.                .
  144.                .
  145.       /* restore coprocessor state */
  146.       asm   frstor float_save.coprocessor_state
  147.  
  148.  
  149.  
  150. [LISTING SEVEN]
  151.  
  152.  
  153.     while( not_done && ! over_run ){   /* non real-time debugging*/
  154.       user_defined_background_task();
  155.       user_defined_real_time_task();
  156.     }
  157.  
  158.  
  159.  
  160. [LISTING EIGHT]
  161.  
  162.   #include <dos.h>
  163.  
  164.   #define  TRUE   -1
  165.   #define  FALSE   0
  166.  
  167.   void user_defined_background_task();
  168.   void set_up_user_background_task();
  169.   void set_down_user_background_task();
  170.   void set_up_user_real_time_task();
  171.   void set_down_user_real_time_task();
  172.   void set_up_real_time_task();
  173.   void set_down_real_time_task();
  174.  
  175.   int not_done = TRUE;
  176.   int over_run = FALSE;
  177.  
  178.   main(){
  179.     set_up_user_real_time_task();     /*initialization section*/
  180.     set_up_real_time_task();
  181.     set_up_user_background_task();
  182.  
  183.     while( not_done && ! over_run){    /*background task loop*/
  184.       user_defined_background_task();
  185.     }
  186.  
  187.     set_down_real_time_task();         /*termination section*/
  188.     set_down_user_background_task();
  189.     set_down_user_real_time_task();
  190.  
  191.     if( over_run )
  192.       printf("Error exit, frame over run\n");
  193.    }
  194.  
  195. /******************************************************/
  196.  
  197.   void interrupt real_time_task();
  198.   void interrupt (*old_clock_func)();
  199.   void set_timer();
  200.   int user_define_divisor = 1; /* initialize in case user forgets */
  201.  
  202.   void set_up_real_time_task()
  203.   {
  204.     void interrupt (*getvect())();
  205.  
  206.     old_clock_func = getvect( 0x08 ); /*save original clock vector*/
  207.     setvect( 0x50, old_clock_func );  /*store in unused location*/
  208.     setvect( 0x08, real_time_task );  /*overwrite with real-time*/
  209.     set_timer( user_define_divisor ); /*set system timer*/
  210.   }
  211.  
  212.   void set_down_real_time_task(){
  213.     setvect( 0x08, old_clock_func ); /*restore clock vector*/
  214.     set_timer( 1 );                  /*reset system timer*/
  215.   }
  216.  
  217. /******************************************************/
  218.  
  219.   union{
  220.     char coprocessor_state[94];
  221.     int control_word;
  222.   } float_save;
  223.  
  224.   int running = FALSE;
  225.   int inter_count = 0;
  226.  
  227.   void interrupt real_time_task(){
  228.     /* save coprocessor state */
  229.     asm   fsave float_save.coprocessor_state
  230.     asm   fldcw float_save.control_word
  231.  
  232.     enable();
  233.  
  234.     if( !running && !over_run ){
  235.       running = TRUE;
  236.       user_defined_real_time_task(); /*real-time function*/
  237.     }else{
  238.       over_run = TRUE;
  239.     };
  240.  
  241.     if( inter_count == user_define_divisor ){
  242.       geninterrupt( 0x50 );     /*call system clock*/
  243.       inter_count = 0;
  244.     }else{
  245.       outport( 0x20, 0x20 );    /*8259 end of interrupt routine*/
  246.       inter_count += 1;
  247.     };
  248.  
  249.     running = FALSE;
  250.  
  251.     /* restore coprocessor state */
  252.     asm   frstor float_save.coprocessor_state
  253.   }
  254.  
  255. /******************************************************/
  256.  
  257.   void set_timer( divisor )
  258.     int divisor;
  259.   {
  260.     int cnt;
  261.     int lo, hi;
  262.  
  263.     cnt = 65536 / divisor;
  264.  
  265.     lo = cnt % 256;
  266.     hi = cnt / 256;
  267.  
  268.     outportb( 0x43, 0x36 );
  269.     outportb( 0x40, lo );    /*write tic counter*/
  270.     outportb( 0x40, hi );
  271.   }
  272.  
  273. /******************************************************/
  274.  
  275.  
  276.  
  277. [LISTING NINE]
  278.  
  279. double x;                     /* DATAPOOL */
  280. extern int user_define_divisor;
  281.  
  282. #define  m     1.0134145    /* define spring-mass constants */
  283. #define  k     10.0
  284. #define  zeta  0.01
  285. #define  x_o   30.0
  286.  
  287. #define  frame_time 0.013725
  288.  
  289. double t = 0.0;   /* real-time */
  290. double c1;    /* real-time constants */
  291. double c2;
  292. double c3;
  293. double c4;
  294.  
  295. void set_up_user_real_time_task(){
  296.   double omega;
  297.   double temp;
  298.   double sqrt();
  299.  
  300.   user_define_divisor = 4;   /* set user divisor counter */
  301.  
  302.   omega = sqrt( k / m );
  303.   temp  = sqrt( 1.0 - zeta * zeta );
  304.  
  305.   c1 = - zeta * omega;     /* compute real-time constants */
  306.   c2 = zeta * x_o / temp;
  307.   c3 = temp * omega;
  308.   c4 = x_o;
  309. }
  310.  
  311. void set_down_user_real_time_task(){   /* no set down necessary */
  312. }
  313.  
  314. void user_defined_real_time_task(){
  315.   double cos();
  316.   double sin();
  317.   double exp();
  318.                    /* spring-mass model */
  319.   x = exp( c1 * t ) * ( c2 * sin( c3 * t ) + c4 * cos( c3 * t ) );
  320.  
  321.   t += frame_time;
  322. }
  323.  
  324.  
  325.  
  326. [LISTING TEN]
  327.  
  328. #include "graphics.h"
  329.  
  330. #define FALSE  0
  331. #define TRUE   -1
  332.  
  333. extern int not_done;
  334. extern double x;   /* DATAPOOL */
  335.  
  336. int x_off = 320;
  337. int y_off = 100;
  338.  
  339. stationary[11][4] = { {   0,   0,   0,  -5 },   /* base */
  340.                       {   0,   0,   7,   0 },
  341.                       { -40,  -5,  40,  -5 },
  342.                       { -35,  -5, -30, -12 },
  343.                       { -25,  -5, -20, -12 },
  344.                       { -15,  -5, -10, -12 },
  345.                       {  -5,  -5,   0, -12 },
  346.                       {   5,  -5,  10, -12 },
  347.                       {  15,  -5,  20, -12 },
  348.                       {  25,  -5,  30, -12 },
  349.                       {  35,  -5,  40, -12 } };
  350.  
  351. void set_up_user_background_task(){
  352.   int  i, j;
  353.   int  g_driver = EGA;
  354.   int  g_mode   = EGAHI;
  355.   char d_path[] = {""};
  356.   int g_error;
  357.  
  358.   if( registerbgidriver( EGAVGA_driver ) < 0 ){   /* EGA driver */
  359.     printf("ERROR: can't register ega/vga driver\n");
  360.     exit();
  361.   };
  362.  
  363.   initgraph( &g_driver, &g_mode, d_path );
  364.   g_error = graphresult();
  365.   if( g_error < 0 ){
  366.     printf("ERROR: %s\n", grapherrormsg(g_error) );
  367.     exit( 0 );
  368.   };
  369.  
  370.   setcolor( YELLOW );
  371.  
  372.   for( i = 0; i < 2; ++i ){   /* setup spring */
  373.     setactivepage( i );
  374.     for( j = 0; j < 11; ++j ){
  375.       line( stationary[j][0] + x_off, stationary[j][1] + y_off, 
  376.             stationary[j][2] + x_off, stationary[j][3] + y_off);
  377.     };
  378.   };
  379.  
  380. }
  381.  
  382. void set_down_user_background_task()
  383. {
  384.   closegraph();
  385. }
  386.  
  387. double stretch[12][4] = { {  7.0,  0.0, -7.0,  5.0 },   /* spring */
  388.                           { -7.0,  5.0,  7.0, 10.0 },
  389.                           {  7.0, 10.0, -7.0, 15.0 },
  390.                           { -7.0, 15.0,  7.0, 20.0 },
  391.                           {  7.0, 20.0, -7.0, 25.0 },
  392.                           { -7.0, 25.0,  7.0, 30.0 },
  393.                           {  7.0, 30.0, -7.0, 35.0 },
  394.                           { -7.0, 35.0,  7.0, 40.0 },
  395.                           {  7.0, 40.0, -7.0, 45.0 },
  396.                           { -7.0, 45.0,  7.0, 50.0 },
  397.                           {  7.0, 50.0, -7.0, 55.0 },
  398.                           { -7.0, 55.0,  7.0, 60.0 } };
  399. int move[ 6][4] = { { -30,  5,  30,   5 },              /* mass */
  400.                     { -30, 40,  30,  40 },
  401.                     { -30,  5, -30,  40 },
  402.                     {  30,  5,  30,  40 },
  403.                     {   0,  0,   0,   5 },
  404.                     {   0,  0,   7,   0 } };
  405.  
  406. void user_defined_background_task(){
  407.   double ratio;
  408.   int x_spring;
  409.   int i, j;
  410.   static int start = 1;
  411.   static int buff[2][100][4];
  412.   static int cnt[2];
  413.   static int b = 0;
  414.   static int p = 0;
  415.  
  416.   if( start ){
  417.     set_page( p );
  418.     p = ( p )? 0: 1;
  419.     setactivepage( p );
  420.   };
  421.  
  422.   if( kbhit() ){
  423.     not_done = FALSE;
  424.   };
  425.  
  426.   x_spring = x + 30.0;
  427.   ratio = 1.0 + ( (double)x / 60.0 );
  428.  
  429.   cnt[b]  = 0;
  430.  
  431.   setcolor( RED );                             /* draw mass */
  432.   for( i = 0, j = cnt[b]; i < 6; ++i, ++j ){
  433.     buff[b][j][0] = move[i][0] + x_off;
  434.     buff[b][j][1] = move[i][1] + y_off + x_spring + 30;
  435.     buff[b][j][2] = move[i][2] + x_off;
  436.     buff[b][j][3] = move[i][3] + y_off + x_spring + 30;
  437.     line( buff[b][j][0], buff[b][j][1], buff[b][j][2], buff[b][j][3] );
  438.   };
  439.   cnt[b] += 6;
  440.  
  441.   setcolor( GREEN );                           /* draw spring */
  442.   for( i = 0, j = cnt[b]; i < 12; ++i, ++j ){
  443.     buff[b][j][0] = stretch[i][0] + x_off;
  444.     buff[b][j][1] = (int)( stretch[i][1] * ratio ) + y_off;
  445.     buff[b][j][2] = stretch[i][2] + x_off;
  446.     buff[b][j][3] = (int)( stretch[i][3] * ratio ) + y_off;
  447.     line( buff[b][j][0], buff[b][j][1], buff[b][j][2], buff[b][j][3] );
  448.   };
  449.   cnt[b] += 12;
  450.  
  451.   b = ( b )? 0: 1;
  452.  
  453.   set_page( p );
  454.   p = ( p )? 0: 1;
  455.   setactivepage( p );   /* switch page */
  456.  
  457.   if( ! start ){
  458.     setcolor( BLACK );                /* undraw picture */
  459.     for( i = 0; i < cnt[b]; ++i )
  460.       line( buff[b][i][0], buff[b][i][1], buff[b][i][2], buff[b][i][3] );
  461.   }else{
  462.     start = 0;
  463.   };
  464. }
  465.  
  466. set_page(n)      /* set visual page */
  467.   int n;
  468. {
  469.   int far *farptr;
  470.   int addr;
  471.  
  472.   setvisualpage( n );
  473.  
  474.   farptr = (int far *)0x00400063;     /* status register address */
  475.   addr = *(farptr) + 6;
  476.  
  477.   while( ( inport( addr ) & 0x08 ) == 0x08 );  /* while in vert retrace */
  478.   while( ( inport( addr ) & 0x08 ) != 0x08 );  /* while not in vert retrace */
  479.  
  480. }
  481.  
  482.  
  483.