home *** CD-ROM | disk | FTP | other *** search
- _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 */
-
- }
-
-