home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_11 / 1011038a < prev    next >
Text File  |  1992-09-16  |  8KB  |  304 lines

  1.  
  2. Listing 2
  3. /* *************************************
  4. *                                      *
  5. *               tiny exec              *
  6. *                                      *
  7. ****************************************
  8.    written by: Charles B. Allison
  9.    Allison Technical Services
  10.    8343 Carvel
  11.    Houston, TX 77036
  12.    PHONE#  (713) 777-0401 | BBS/FAX (713) 777-4746
  13. ****************************************
  14. version 1.1
  15. last change 6-3-92 11:35
  16. */
  17. /* ***** include files ****** */
  18. #include <dos.h>
  19. #include <conio.h>
  20. #include <stdio.h>
  21. #include <time.h>
  22. #include "tinyexec.h"
  23. /* ********* define statements ********* */
  24. /* #define DEBUG 1*/
  25. #define MICROSOFT 1
  26. #define NUM_TIMERS 3 /* number of timers */
  27. #define NUM_TASKS 3  /* number of tasks  */
  28. #define TASK_TICKS 2 /* TASK_TICKS is the # of */
  29.         /* rtc clock ticks between task exec runs */
  30. #define OLD_TICKS 1
  31. /* OLD_TICKS is the number of rtc clock ticks between
  32. running  oldtimer, the system clock at 18.2Hz */
  33. #define NORMAL_COUNT 0
  34. /* value normally used in counter 65536 (= 0)*/
  35. #define RTC_COUNT (unsigned)((65536L/OLD_TICKS)&0xffff)
  36. /* value to be used in rtc interrupt rate
  37.        - relates to OLD_TICKS */
  38. #ifdef MICROSOFT /* Microsoft compatibility */
  39. #include <graph.h>
  40. #pragma intrinsic (inp, outp, _enable, _disable)
  41. #define gotoxy(x,y) _settextposition(y,x)
  42. #define clrscr() _clearscreen(_GWINDOW)
  43. #endif
  44. /* ********** Inline Functions ************ */
  45. /* -------- set_timer ----------- */
  46. /* set timer i to count down in time t */
  47. #define set_timer(i,t) _disable();\
  48. timers[i]=t;\
  49. _enable();
  50. /* -------- req_task ----------- */
  51. /* request task i  */
  52. #define req_task(i) _disable();\
  53. task_flag[i] = REQ_TASK;\
  54. _enable();
  55. /* -------resume_task -------- */
  56. #define resume_task(i) _disable();\
  57. task_flag[i] |= REQ_TASK;\
  58. task_flag[i]++;\
  59. _enable();
  60. /* use following inline when ints are disabled */
  61. /* -------- iset_timer ----------- */
  62. /* set timer i to count down in time t */
  63. #define iset_timer(i,t) timers[i]=t;
  64. /* -------- ireq_task ----------- */
  65. /* request task i ints disabled */
  66. #define ireq_task(i) task_flag[i] = REQ_TASK;
  67. /* -------iresume_task -------- */
  68. /* resume task - interrupts disabled */
  69. #define iresume_task(i) task_flag[i] |= REQ_TASK;\
  70. task_flag[i]++;
  71. /* ******** function prototypes ************* */
  72. void main(void);
  73. void task0(void);
  74. void task1(void);
  75. void init_rtc(void);  /* set up rtc/tasker */
  76. void close_rtc(void); /* shut down rtc/tasker */
  77. void init_cntr(unsigned count);
  78. void interrupt rtcint(void);
  79. void timr0(void);
  80. void timr1(void);
  81. void timr2(void);
  82. /* ******* tiny exec variables ******** */
  83. /* timer counter and function arrays */
  84. unsigned timers[NUM_TIMERS] = { 0, 0, 0 };
  85. void (*timer[NUM_TIMERS]) (void)={timr0,timr1,timr2};
  86. /* ticks between task exec */
  87. unsigned task_time = TASK_TICKS;
  88. /* new timer ticks between old timer calls */
  89. unsigned old_time=OLD_TICKS;
  90. /* storage for old system clock int vector*/
  91. void (interrupt far *oldtimer)(void);
  92. /* task flag and function arrays */
  93. unsigned task_flag[NUM_TASKS] = {0,0,IN_PROC};
  94. void (*task[NUM_TASKS])(void) = {task0,task1,main};
  95. int cur_task_num;/* indicates what is current task */
  96. /* *************** functions ***************** */
  97. /* combination real time clock and task exec */
  98. void interrupt rtcint(void)
  99. {
  100. int i; /* local stack variable */
  101. /* handle timers here, then 18.2Hz system clock
  102. then do tasks
  103. ***************************************** */
  104. for(i = 0;i < NUM_TIMERS;i++ )
  105.    {
  106.     if (timers[i])
  107.       {
  108.        if(!(--timers[i]))  (*timer[i])();
  109.       }
  110.    }
  111. /* call system clock 18.2 x per second */
  112. if(!(--old_time))
  113.   {
  114.    old_time=OLD_TICKS;
  115. #ifndef DEBUG
  116.   (*oldtimer)();      /* call old timer here */
  117.   }  else {
  118.     outp (XT8259,CLR_INT);  /* clear int req */
  119. #endif
  120.   }
  121. /* ------end of timers ---------- */
  122. task_time--;    /* one less time tick */
  123. if(task_time) return; /*not time for task exec */
  124. task_time = TASK_TICKS; /* do tasks now*/
  125. /* --------- task exec section ---------- */
  126. for(i = 0; i < NUM_TASKS;i++)
  127.  {
  128.  if (task_flag[i] & IN_PROC)
  129.   {
  130.    cur_task_num = i;
  131.    return;  /* found one in process so return */
  132.   }
  133.  if(task_flag[i] & REQ_TASK)
  134.   {
  135.    task_flag[i]=IN_PROC | (task_flag[i] & ~REQ_TASK);
  136.         /* begin task */
  137.         cur_task_num = i; /* current task in process*/
  138.         _enable();        /* now allow interrupts */
  139.         (*task[i]) ();    /* do task */
  140.         _disable();
  141.         task_flag[i] &= ~IN_PROC;  /* done */
  142.        }
  143.   }
  144. }
  145. /* ***************** init_rtc ******************** */
  146. void init_rtc(void)  /* routine to set up rtc/tasker */
  147. {
  148.  _disable();
  149.  oldtimer = _dos_getvect(TIMER); /* get timer vector*/
  150.  _dos_setvect(TIMER,rtcint);  /* set real time timer */
  151.  init_cntr( RTC_COUNT);
  152.  _enable();
  153. }
  154. /* ****************** close_rtc ******************* */
  155. void close_rtc(void) /* shut down rtc/tasker */
  156. {
  157.  _disable();
  158.  _dos_setvect(TIMER,oldtimer); /* restore timer */
  159.  init_cntr( NORMAL_COUNT);
  160.  _enable();
  161. }
  162. /* *************** init_cntr ***************** */
  163. void init_cntr(unsigned count)
  164. {
  165.  int lowb, highb;
  166.  lowb = count % 256;
  167.  highb = count / 256;
  168.  outp (TIMR1_C,LOAD_T1); /* load count for 8253 */
  169.  outp (TIMR1_T1, lowb);
  170.  outp (TIMR1_T1, highb);
  171. }
  172. /* **** Example main and tasks *********** */
  173. void set_beep(void);
  174. void clr_beep(void);
  175. void tsk1sub1 (void); /*subtasks for task 1 */
  176. void tsk1sub2 (void);
  177.  
  178. int beep_len = 6; /* default to about 1/3 sec */
  179.  
  180. #define SPKR_CNTRL 0x61
  181. #define SPKR_ENABLE 0x03
  182.  
  183. #define SPKR_DISABLE 0xfc
  184.  
  185. int t0_flag =0, t1_flag = 0;
  186. int timer0 = 0,timer1 = 0,timer2 = 0;
  187.  
  188. int state_of_tasks[NUM_TASKS];
  189. int state_of_timers[NUM_TIMERS];
  190. /* --------- main ------------ */
  191. void main (void)
  192. {
  193. int i,oldt0,oldtmr0=0,endit = 1;
  194. time_t t;
  195. #ifndef DEBUG
  196.  init_rtc(); /* open rtc */
  197. #endif
  198. clrscr();
  199. gotoxy(1,1);
  200. printf("Counts for t0_flag t1_flag ");
  201. printf("timer0 timer1 timer2");
  202. gotoxy(1,4);
  203. printf("task and timer flag images");
  204. gotoxy(1,5);
  205. printf("task0 task1 timer0 timer1 timer2");
  206. set_timer(0,18); /* begin timer 0 in 12 ticks */
  207. req_task(0);     /* request task 0 to run once */
  208. set_timer(1,90); /*begin timer 1 in 90 ticks */
  209. while(endit)
  210.  {
  211.   if(kbhit())
  212.    {
  213.     switch(getch()) {
  214.      case '\x1b':  /* exit on Esc */
  215.       endit = 0;
  216.       break;
  217.      case ' ':
  218.       req_task(1);  /* do a beep*/
  219.       break;
  220.      default:
  221.       break;
  222.     } /* end of switch */
  223.   } /* end of if */
  224. if(t0_flag != oldt0)
  225.  {
  226.   oldt0=t0_flag;
  227.   gotoxy(1,6); /* show current tasks and timers */
  228.   for(i=0;i<NUM_TASKS-1;i++)
  229.     printf("%4x  ",state_of_tasks[i]);
  230.   for(i=0;i<NUM_TIMERS;i++)
  231.     printf(" %4d  ",state_of_timers[i]);
  232.  }
  233. #ifdef DEBUG
  234.  rtcint();
  235. #endif
  236. gotoxy(1,2);
  237. printf("           %4d    %4d     %4d   %4d   %4d",\
  238.       t0_flag,t0_flag,timer0,timer1,timer2);
  239.   if(timer0 != oldtmr0)
  240.    {
  241.     oldtmr0 = timer0;
  242.     t=time(NULL);
  243.     gotoxy(1,20);
  244.     printf("%s",ctime(&t));
  245.    }
  246.  } /* end of while */
  247. #ifndef DEBUG
  248.  close_rtc();  /* restore rtc */
  249. #endif
  250. }
  251. /* *********** tasks ************** */
  252. /* -------- task0 ----------- */
  253. void task0(void)
  254. {
  255. /* get current timer and task states */
  256. int i;
  257. t0_flag++;
  258. for(i=0;i<NUM_TIMERS;i++)
  259.   state_of_timers[i] = timers[i];
  260. for(i=0;i<NUM_TASKS;i++)
  261.  state_of_tasks[i] = task_flag[i];
  262. }
  263. /* ------- task1 --------- */
  264. void task1(void)
  265. { /* handle beeps - 2 subtasks */
  266. static void (*subexec1[])(void) = {
  267.   tsk1sub1,
  268.   tsk1sub2
  269.   };
  270. t1_flag++;
  271. (*subexec1[task_flag[cur_task_num] & 0x01])();
  272. } /* end task 1 */
  273. void tsk1sub1 (void)
  274. {                /* turn on beep */
  275. outp(SPKR_CNTRL,inp(SPKR_CNTRL)| SPKR_ENABLE);
  276. set_timer(2,beep_len); /*beep length*/
  277. }
  278. void tsk1sub2(void)
  279. {              /* turn off beep here */
  280. outp(SPKR_CNTRL, inp(SPKR_CNTRL) & SPKR_DISABLE);
  281. }
  282. /* ***************** timers ********************** */
  283. /*Note - timers are run with interrupts disabled*/
  284. void timr0(void)
  285. {
  286. timer0++; /* count of timer runs */
  287. timers[0]=18; /* set time again */
  288. }
  289. void timr1(void)
  290. {
  291. timer1++; /* count of timer runs */
  292. timers[1]=2; /* set timer again */
  293. ireq_task(0);  /* request task 0 */
  294. }
  295. void timr2(void)
  296. /* beep turn off timer */
  297. {
  298. timer2++; /* count of timer runs */
  299. iresume_task(1);
  300. }
  301.  
  302.  
  303.  
  304.