home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / RAYCAST.ZIP / TIMER.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-12  |  2.6 KB  |  125 lines

  1. #include "os.h"
  2. #include "timer.h"
  3. #include "sound.h"
  4.  
  5. long update_num, update_save;
  6.  
  7. #ifdef OS_DOS
  8. #include <i86.h>
  9. #include <dos.h>
  10. #include <conio.h>
  11.  
  12. #define TIMER_INT 0x8
  13. #define UPDATE_INT 0x1c
  14.  
  15. // These, are some weird port numbers for setting up a clock double-
  16. // I'm not even sure why the whole clock double works
  17.  
  18. #define CMD_REG 0x43 
  19. #define CHAN_0 0x40
  20. #define INT_CONTROL     0x20         // interrupt control register 
  21.  
  22. BOOL right_time_mode;
  23. BOOL update_mode;  // Used for timer interrupt
  24.  
  25. void (_interrupt _far * Old_Update_Isr)(); // holds old update interrupt
  26. void (_interrupt _far * Old_Timer_Isr)(); // holds old timer interrupt
  27.  
  28. void SetTimeSpeed(unsigned char speed)
  29. {
  30.    // This tells the hardware to double the clock speed
  31.    // I'm not sure why this works- I got it from a magazine
  32.    long tempval; unsigned char lowhalf, highhalf;
  33.    tempval=65536/speed;
  34.    lowhalf=(unsigned char)(tempval & 0x000000ff);
  35.    highhalf= (unsigned char)((tempval & 0x0000ff00) >> 8);
  36.    outp(CMD_REG, 0x36);
  37.    outp(CHAN_0, lowhalf);
  38.    outp(CHAN_0, highhalf);
  39. }
  40.  
  41. void Suspend_Time() {
  42.    update_save=update_num;
  43.    update_num=0;
  44. }
  45.  
  46. void Resume_Time() {
  47.    update_num=update_save;
  48. }
  49.  
  50. void _interrupt _far New_Update_Int() {
  51.   Update_Sound();
  52.   update_num++;
  53. }
  54.  
  55. void _interrupt _far New_Timer_Int(void)
  56. {
  57.    // Ok, in this interrupt, the  old timer int is called only half the time, and since the clock is doubled,
  58.    // this keeps the internal time right. The update interrupt is always called (either explicitly
  59.    // or implicitly), causing the updates to be twice as fast.
  60.  
  61.    if (update_mode) {
  62.       update_mode=FALSE;
  63.       if (!right_time_mode) {
  64.           right_time_mode=TRUE;
  65.           outp(0x20, 0x20);
  66.           _chain_intr(New_Update_Int);
  67.        } else {
  68.           right_time_mode=FALSE;
  69.           _chain_intr(Old_Timer_Isr);
  70.        } /* endif */
  71.    } else {
  72.        outp(0x20, 0x20);
  73.        Update_Sound();
  74.        update_mode=TRUE;
  75.    }
  76.  
  77. }
  78.  
  79. #endif
  80.  
  81. void Init_Timer() {
  82. update_num=0;
  83.  
  84. #ifdef OS_DOS
  85.  
  86. update_mode=FALSE;
  87. right_time_mode=FALSE;
  88.  
  89. Old_Timer_Isr = _dos_getvect(TIMER_INT);
  90.  
  91. _dos_setvect(TIMER_INT, New_Timer_Int);
  92.  
  93. SetTimeSpeed(4);
  94.  
  95. Old_Update_Isr = _dos_getvect(UPDATE_INT);
  96.  
  97. _dos_setvect(UPDATE_INT, New_Update_Int);
  98. #endif
  99. }
  100.  
  101. void Reset_Timer() {
  102.    update_num=0;
  103. }
  104.  
  105. void Close_Timer() {
  106. #ifdef OS_DOS
  107.    _dos_setvect(TIMER_INT, Old_Timer_Isr);
  108.    SetTimeSpeed(1);
  109.    _dos_setvect(UPDATE_INT, Old_Update_Isr);
  110. #endif
  111. }
  112.  
  113.  
  114. long Get_Update_Num() {
  115. #ifdef OS_DOS
  116.   return update_num;
  117. #endif
  118.  
  119. #ifdef OS_WINDOWS
  120.   return (update_num++);
  121. #endif
  122. }
  123.  
  124.  
  125.