textfiles/computers/bowling.asc

483 lines
11 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

_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 */
}