💾 Archived View for spam.works › mirrors › textfiles › computers › bowling.asc captured on 2023-06-14 at 16:00:35.

View Raw

More Information

-=-=-=-=-=-=-

_Real-Time Modleing with MS-DOS_
by David Bowling

[LISTING ONE]


  #include <dos.h>

  #define  TRUE   -1
  #define  FALSE   0

  void user_defined_background_task();
  void set_up_user_background_task();
  void set_down_user_background_task();
  void set_up_user_real_time_task();
  void set_down_user_real_time_task();
  void set_up_real_time_task();
  void set_down_real_time_task();

  int not_done = TRUE;
  int over_run = FALSE;

  main(){
    set_up_user_real_time_task();     /*initialization section*/
    set_up_real_time_task();
    set_up_user_background_task();

    while( not_done && ! over_run){    /*background task loop*/  
    user_defined_background_task();
    }

    set_down_real_time_task();         /*termination section*/   
    set_down_user_background_task();
    set_down_user_real_time_task();

    if( over_run )
      printf("Error exit, frame over run\n");
   }





[LISTING TWO]

  void interrupt real_time_task();
  void interrupt (*old_clock_func)();
  void set_timer();
  int user_define_divisor = 1; /*initialize in case user forgets*/

  void set_up_real_time_task()
  {
    void interrupt (*getvect())();

    old_clock_func = getvect( 0x08 );/*save original clock vector*/
     setvect( 0x50, old_clock_func );/*store in unused location*/
     setvect( 0x08, real_time_task ); /*overwrite with real-time*/
    set_timer( user_define_divisor ); /*set system timer*/
  }

  void set_down_real_time_task(){
    setvect( 0x08, old_clock_func ); /*restore clock vector*/
    set_timer( 1 );                  /*reset system timer*/
  }


[LISTING THREE]


  int running = FALSE;
  int inter_count = 0;

  void interrupt real_time_task(){
    enable();

    if( !running && !over_run ){
      running = TRUE;
      user_defined_real_time_task(); /*real-time function*/
    }else{
      over_run = TRUE;
    };

    if( inter_count == user_define_divisor ){
      geninterrupt( 0x50 );     /*call system clock*/
      inter_count = 0;
    }else{
      outport( 0x20, 0x20 );    /*8259 end of interrupt routine*/
      inter_count += 1;
    };

    running = FALSE;
  }

 



[LISTING FOUR]

  void set_timer( divisor )
    int divisor;
  {
    int cnt;
    int lo, hi;

    cnt = 65536 / divisor;

    lo = cnt % 256;
    hi = cnt / 256;

    outportb( 0x43, 0x36 );
    outportb( 0x40, lo );    /*write tic counter*/
    outportb( 0x40, hi );
  }


[LISTING FIVE] 

  int i = 0;  /* DATAPOOL */

  user_defined_background_task(){
    printf("i = %d\n", i );
  }

  user_defined_real_time_function(){
    i += 1;
  }




[LISTING SIX]

      union{
       char coprocessor_state[94];
       int control_word;
     }float_save;
  
      /* save coprocessor state */
      asm   fsave float_save.coprocessor_state
      asm   fldcw float_save.control_word
               .
               .
               .
      /* restore coprocessor state */
      asm   frstor float_save.coprocessor_state



[LISTING SEVEN]


    while( not_done && ! over_run ){   /* non real-time debugging*/
      user_defined_background_task();
      user_defined_real_time_task();
    }



[LISTING EIGHT]

  #include <dos.h>

  #define  TRUE   -1
  #define  FALSE   0

  void user_defined_background_task();
  void set_up_user_background_task();
  void set_down_user_background_task();
  void set_up_user_real_time_task();
  void set_down_user_real_time_task();
  void set_up_real_time_task();
  void set_down_real_time_task();

  int not_done = TRUE;
  int over_run = FALSE;

  main(){
    set_up_user_real_time_task();     /*initialization section*/
    set_up_real_time_task();
    set_up_user_background_task();

    while( not_done && ! over_run){    /*background task loop*/
      user_defined_background_task();
    }

    set_down_real_time_task();         /*termination section*/
    set_down_user_background_task();
    set_down_user_real_time_task();

    if( over_run )
      printf("Error exit, frame over run\n");
   }

/******************************************************/

  void interrupt real_time_task();
  void interrupt (*old_clock_func)();
  void set_timer();
  int user_define_divisor = 1; /* initialize in case user forgets */

  void set_up_real_time_task()
  {
    void interrupt (*getvect())();

    old_clock_func = getvect( 0x08 ); /*save original clock vector*/
    setvect( 0x50, old_clock_func );  /*store in unused location*/
    setvect( 0x08, real_time_task );  /*overwrite with real-time*/
    set_timer( user_define_divisor ); /*set system timer*/
  }

  void set_down_real_time_task(){
    setvect( 0x08, old_clock_func ); /*restore clock vector*/
    set_timer( 1 );                  /*reset system timer*/
  }

/******************************************************/

  union{
    char coprocessor_state[94];
    int control_word;
  } float_save;

  int running = FALSE;
  int inter_count = 0;

  void interrupt real_time_task(){
    /* save coprocessor state */
    asm   fsave float_save.coprocessor_state
    asm   fldcw float_save.control_word

    enable();

    if( !running && !over_run ){
      running = TRUE;
      user_defined_real_time_task(); /*real-time function*/
    }else{
      over_run = TRUE;
    };

    if( inter_count == user_define_divisor ){
      geninterrupt( 0x50 );     /*call system clock*/
      inter_count = 0;
    }else{
      outport( 0x20, 0x20 );    /*8259 end of interrupt routine*/
      inter_count += 1;
    };

    running = FALSE;

    /* restore coprocessor state */
    asm   frstor float_save.coprocessor_state
  }

/******************************************************/

  void set_timer( divisor )
    int divisor;
  {
    int cnt;
    int lo, hi;

    cnt = 65536 / divisor;

    lo = cnt % 256;
    hi = cnt / 256;

    outportb( 0x43, 0x36 );
    outportb( 0x40, lo );    /*write tic counter*/
    outportb( 0x40, hi );
  }

/******************************************************/



[LISTING NINE]

double x;                     /* DATAPOOL */
extern int user_define_divisor;

#define  m     1.0134145    /* define spring-mass constants */
#define  k     10.0
#define  zeta  0.01
#define  x_o   30.0

#define  frame_time 0.013725

double t = 0.0;   /* real-time */
double c1;    /* real-time constants */
double c2;
double c3;
double c4;

void set_up_user_real_time_task(){
  double omega;
  double temp;
  double sqrt();

  user_define_divisor = 4;   /* set user divisor counter */

  omega = sqrt( k / m );
  temp  = sqrt( 1.0 - zeta * zeta );

  c1 = - zeta * omega;     /* compute real-time constants */
  c2 = zeta * x_o / temp;
  c3 = temp * omega;
  c4 = x_o;
}

void set_down_user_real_time_task(){   /* no set down necessary */
}

void user_defined_real_time_task(){
  double cos();
  double sin();
  double exp();
                   /* spring-mass model */
  x = exp( c1 * t ) * ( c2 * sin( c3 * t ) + c4 * cos( c3 * t ) );

  t += frame_time;
}



[LISTING TEN]

#include "graphics.h"

#define FALSE  0
#define TRUE   -1

extern int not_done;
extern double x;   /* DATAPOOL */

int x_off = 320;
int y_off = 100;

stationary[11][4] = { {   0,   0,   0,  -5 },   /* base */
                      {   0,   0,   7,   0 },
                      { -40,  -5,  40,  -5 },
                      { -35,  -5, -30, -12 },
                      { -25,  -5, -20, -12 },
                      { -15,  -5, -10, -12 },
                      {  -5,  -5,   0, -12 },
                      {   5,  -5,  10, -12 },
                      {  15,  -5,  20, -12 },
                      {  25,  -5,  30, -12 },
                      {  35,  -5,  40, -12 } };

void set_up_user_background_task(){
  int  i, j;
  int  g_driver = EGA;
  int  g_mode   = EGAHI;
  char d_path[] = {""};
  int g_error;

  if( registerbgidriver( EGAVGA_driver ) < 0 ){   /* EGA driver */
    printf("ERROR: can't register ega/vga driver\n");
    exit();
  };

  initgraph( &g_driver, &g_mode, d_path );
  g_error = graphresult();
  if( g_error < 0 ){
    printf("ERROR: %s\n", grapherrormsg(g_error) );
    exit( 0 );
  };

  setcolor( YELLOW );

  for( i = 0; i < 2; ++i ){   /* setup spring */
    setactivepage( i );
    for( j = 0; j < 11; ++j ){
      line( stationary[j][0] + x_off, stationary[j][1] + y_off, 
            stationary[j][2] + x_off, stationary[j][3] + y_off);
    };
  };

}

void set_down_user_background_task()
{
  closegraph();
}

double stretch[12][4] = { {  7.0,  0.0, -7.0,  5.0 },   /* spring */
                          { -7.0,  5.0,  7.0, 10.0 },
                          {  7.0, 10.0, -7.0, 15.0 },
                          { -7.0, 15.0,  7.0, 20.0 },
                          {  7.0, 20.0, -7.0, 25.0 },
                          { -7.0, 25.0,  7.0, 30.0 },
                          {  7.0, 30.0, -7.0, 35.0 },
                          { -7.0, 35.0,  7.0, 40.0 },
                          {  7.0, 40.0, -7.0, 45.0 },
                          { -7.0, 45.0,  7.0, 50.0 },
                          {  7.0, 50.0, -7.0, 55.0 },
                          { -7.0, 55.0,  7.0, 60.0 } };
int move[ 6][4] = { { -30,  5,  30,   5 },              /* mass */
                    { -30, 40,  30,  40 },
                    { -30,  5, -30,  40 },
                    {  30,  5,  30,  40 },
                    {   0,  0,   0,   5 },
                    {   0,  0,   7,   0 } };

void user_defined_background_task(){
  double ratio;
  int x_spring;
  int i, j;
  static int start = 1;
  static int buff[2][100][4];
  static int cnt[2];
  static int b = 0;
  static int p = 0;

  if( start ){
    set_page( p );
    p = ( p )? 0: 1;
    setactivepage( p );
  };

  if( kbhit() ){
    not_done = FALSE;
  };

  x_spring = x + 30.0;
  ratio = 1.0 + ( (double)x / 60.0 );

  cnt[b]  = 0;

  setcolor( RED );                             /* draw mass */
  for( i = 0, j = cnt[b]; i < 6; ++i, ++j ){
    buff[b][j][0] = move[i][0] + x_off;
    buff[b][j][1] = move[i][1] + y_off + x_spring + 30;
    buff[b][j][2] = move[i][2] + x_off;
    buff[b][j][3] = move[i][3] + y_off + x_spring + 30;
    line( buff[b][j][0], buff[b][j][1], buff[b][j][2], buff[b][j][3] );
  };
  cnt[b] += 6;

  setcolor( GREEN );                           /* draw spring */
  for( i = 0, j = cnt[b]; i < 12; ++i, ++j ){
    buff[b][j][0] = stretch[i][0] + x_off;
    buff[b][j][1] = (int)( stretch[i][1] * ratio ) + y_off;
    buff[b][j][2] = stretch[i][2] + x_off;
    buff[b][j][3] = (int)( stretch[i][3] * ratio ) + y_off;
    line( buff[b][j][0], buff[b][j][1], buff[b][j][2], buff[b][j][3] );
  };
  cnt[b] += 12;

  b = ( b )? 0: 1;

  set_page( p );
  p = ( p )? 0: 1;
  setactivepage( p );   /* switch page */

  if( ! start ){
    setcolor( BLACK );                /* undraw picture */
    for( i = 0; i < cnt[b]; ++i )
      line( buff[b][i][0], buff[b][i][1], buff[b][i][2], buff[b][i][3] );
  }else{
    start = 0;
  };
}

set_page(n)      /* set visual page */
  int n;
{
  int far *farptr;
  int addr;

  setvisualpage( n );

  farptr = (int far *)0x00400063;     /* status register address */
  addr = *(farptr) + 6;

  while( ( inport( addr ) & 0x08 ) == 0x08 );  /* while in vert retrace */
  while( ( inport( addr ) & 0x08 ) != 0x08 );  /* while not in vert retrace */

}