home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / bios / t1.c < prev    next >
Text File  |  1998-06-08  |  5KB  |  130 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. #include <dos.h>
  16.  
  17. #define    TDATA           0x40
  18. #define    TCOMMAND        0x43
  19. #define  TMODE2            0x34            // Set mode 2
  20.  
  21. #define disable _disable
  22. #define enable _enable
  23. #define outportb outp
  24. #define inportb inp
  25.  
  26. // n_milliseconds 0-32768...
  27. void ms_delay_asm(short n_milliseconds);
  28. #pragma aux ms_delay_asm parm [edx] modify exact [esi edi eax ebx ecx edx] =             \
  29. "    mov    dx, ax                                                                                            "\
  30. "    sti                            //Disable interrupts                                                    "\
  31. "    xor    ah, ah                //Load timer latch command (0) into ah                            "\
  32. "    out    TCOMMAND, ah        //Send command                                                            "\
  33. "    in        al, TDATA            //Read and throw away low byte                                    "\
  34. "    in        al, TDATA            //Read high byte                                                        "\
  35. "    sti                           //Re-enable interrupts                                                "\
  36. "    push    ax                        //Store initial timer count                                        "\
  37. "                                                                                                                             " \
  38. "    mov    ax, dx;      //n_milliseconds; All this code is to calculate n_milliseconds * 4.659     " \
  39. "    mov    bx, 37                                                                                          "    \
  40. "    imul    bx                      // dx:ax = n_milliseconds * 37                                      "    \
  41. "    mov    si, dx                                                                                          "    \
  42. "    mov    di, ax                                                                                          "    \
  43. "    mov    cl, 3                                                                                              "    \
  44. "    shr    di, cl                                                                                          "    \
  45. "    shr    si, cl                //si:di /= 8                                                          "    \
  46. "    mov    cl, 5                                                                                              "    \
  47. "    shl    dx, cl                                                                                          "    \
  48. "    or        di, dx                //Our target value is stored in SI:DI now                      "    \
  49. "    xor    cx, cx                //Clear our 32-bit counter in cx:dx                              "    \
  50. "    xor    bx, bx                                                                                          "    \
  51. "                                                                                                              "    \
  52. "    pop    ax                        //Get initial timer value, so that all the divides          "    \
  53. "                                    //above count towards the total time waiting.              "    \
  54. "                                                                                                              "    \
  55. "MsTimerLoop:                                                                                              "    \
  56. "    mov    dx, ax                //Store last read timer value                                      "    \
  57. "    sti                            //Disable interrupts                                                  "    \
  58. "    xor    ah, ah                //Clearing AH timer latch command                              "    \
  59. "    out    TCOMMAND, ah        //Send command                                                          "    \
  60. "    in        al, TDATA            //Read and throw away low byte                                  "    \
  61. "    in        al, TDATA            //Read high byte                                                      "    \
  62. "    sti                            //Re-enable interrupts                                              "    \
  63. "    cmp    ax, dx                //Check for timer counter wrapping                              "    \
  64. "    jl        MsNoWrap                                                                                          "    \
  65. "    add    dx, 256                //If it wrapped, add 256 to total count                      "    \
  66. "MsNoWrap:                                                                                                  "    \
  67. "    sub    dx, ax                //Calculate delta time                                              "    \
  68. "    add    bx, dx                //Add delta time to total counter in cx:bx                  "    \
  69. "    adc    cx, 0                    //(32 bit add)                                                          "    \
  70. "                                                                                                              "    \
  71. "    cmp    cx, si                //See if we are done by checking                               "    \
  72. "    ja        MsDone                // to see if cx:bx > si:di                                          "    \
  73. "    jb        MsTimerLoop                                                                                      "    \
  74. "    cmp    bx, di                                                                                          "    \
  75. "    jb        MsTimerLoop                                                                                      "    \
  76. "MsDone:                            //cx:bx is > si:di, so we're done                              "\
  77.  
  78. // n_milliseconds 0-32768...
  79. void ms_delay(short n_milliseconds)
  80. {
  81.     unsigned long count, target;        
  82.     unsigned char reading;
  83.     unsigned short delta;
  84.  
  85.     disable();
  86.     outportb( TCOMMAND, 0 );        // Latch timer 0
  87.     inportb( TDATA );                    // Low byte
  88.     reading = inportb( TDATA );    // High byte
  89.     enable();
  90.  
  91.     target = (unsigned long)n_milliseconds*37;        // Should be x 4.659
  92.     target /= 8;
  93.     count = 0;
  94.     delta = reading;
  95.  
  96.     while(1)    {
  97.         disable();
  98.         outportb( TCOMMAND, 0 );        // Latch timer 0
  99.         inportb( TDATA );                    // Low byte
  100.         reading = inportb( TDATA );    // High byte
  101.         enable();
  102.         if ( reading > delta )    
  103.             delta += 256;
  104.         delta -= reading;
  105.         count += delta;
  106.         if ( count > target ) return;
  107.         delta = reading;
  108.     }
  109. }
  110.  
  111. void main()
  112. {
  113.     int i;
  114.     disable();
  115.     outportb( TCOMMAND, TMODE2 );        // Set timer to count in mode 2
  116.     outportb( TDATA, 0 );
  117.     outportb( TDATA, 0 );
  118.     enable();
  119.     printf( "Press a key to start\n" );
  120.     getch();
  121.     printf( "Go...\n" );
  122.     for (i=0;i<3000; i++ )    {
  123.         ms_delay_asm( 10 );
  124.     }
  125.     printf( "Stop\n" );
  126.  
  127. }
  128.  
  129. 
  130.