1. #define uint8 unsigned char
  2. #define int8 char
  3. #define uint16 unsigned short
  4. #define int16 short
  5. #define uint32 unsigned long
  6. #define int32 long
  7. #define uint64 unsigned long long
  8. #define int64 long long
  9.  
  10.  
  11. #define SCREEN_WIDTH 80
  12. #define SCREEN_HEIGHT 25
  13.  
  14. static uint16 pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0, tpos1, tpos2, tpos3, tpos4;
  15. static int sintab[512] = {
  16.        0, 12, 25, 37, 50, 62, 75, 87, 100, 112, 125, 137, 150, 162, 175, 187, 199, 212, 224, 236, 248, 260, 273, 285, 297, 309, 321, 333, 344, 356, 368, 380, 391,
  17.    403, 414, 426, 437, 449, 460, 471, 482, 493, 504, 515, 526, 537, 547, 558, 568, 579, 589, 599, 609, 620, 629, 639, 649, 659, 668, 678, 687, 696, 706, 715, 724,
  18.      732, 741, 750, 758, 767, 775, 783, 791, 799, 807, 814, 822, 829, 837, 844, 851, 858, 865, 871, 878, 884, 890, 897, 903, 908, 914, 920, 925, 930, 936, 941, 946,
  19.      950, 955, 959, 964, 968, 972, 976, 979, 983, 986, 990, 993, 996, 999, 1001, 1004, 1006, 1008, 1010, 1012, 1014, 1016, 1017, 1019, 1020, 1021, 1022, 1022, 1023, 1023, 1023, 1023,
  20.      1023, 1023, 1023, 1022, 1022, 1021, 1020, 1019, 1017, 1016, 1014, 1012, 1010, 1008, 1006, 1004, 1001, 999, 996, 993, 990, 986, 983, 979, 976, 972, 968, 964, 959, 955, 950, 946,
  21.       941, 936, 930, 925, 920, 914, 908, 903, 897, 890, 884, 878, 871, 865, 858, 851, 844, 837, 829, 822, 814, 807, 799, 791, 783, 775, 767, 758, 750, 741, 732, 724,
  22.      715, 706, 696, 687, 678, 668, 659, 649, 639, 630, 620, 610, 599, 589, 579, 568, 558, 547, 537, 526, 515, 504, 493, 482, 471, 460, 449, 437, 426, 414, 403, 391,
  23.      380, 368, 356, 344, 333, 321, 309, 297, 285, 273, 260, 248, 236, 224, 212, 199, 187, 175, 162, 150, 137, 125, 112, 100, 87, 75, 62, 50, 37, 25, 12, 0,
  24.      -12, -25, -37, -50, -62, -75, -87, -100, -112, -125, -137, -150, -162, -175, -187, -199, -212, -224, -236, -248, -260, -273, -285, -297, -309, -321, -333, -344, -356, -368, -380, -391,
  25.      -403, -414, -426, -437, -449, -460, -471, -482, -493, -504, -515, -526, -537, -547, -558, -568, -579, -589, -599, -609, -620, -629, -639, -649, -659, -668, -678, -687, -696, -706, -715, -724,
  26.       -732, -741, -750, -758, -767, -775, -783, -791, -799, -807, -814, -822, -829, -837, -844, -851, -858, -865, -871, -878, -884, -890, -897, -903, -908, -914, -920, -925, -930, -936, -941, -946,
  27.       -950, -955, -959, -964, -968, -972, -976, -979, -983, -986, -990, -993, -996, -999, -1001, -1004, -1006, -1008, -1010, -1012, -1014, -1016, -1017, -1019, -1020, -1021, -1022, -1022, -1023, -1023, -1023, -1023,
  28.       -1023, -1023, -1023, -1022, -1022, -1021, -1020, -1019, -1017, -1016, -1014, -1012, -1011, -1008, -1006, -1004, -1001, -999, -996, -993, -990, -986, -983, -979, -976, -972, -968, -964, -959, -955, -950, -946,
  29.        -941, -936, -930, -925, -920, -914, -908, -903, -897, -890, -884, -878, -871, -865, -858, -851, -844, -837, -829, -822, -814, -807, -799, -791, -783, -775, -767, -758, -750, -741, -732, -724,
  30.       -715, -706, -696, -687, -678, -668, -659, -649, -639, -630, -620, -610, -599, -589, -579, -568, -558, -547, -537, -526, -515, -504, -493, -482, -471, -460, -449, -437, -426, -414, -403, -391,
  31.       -380, -368, -356, -345, -333, -321, -309, -297, -285, -273, -261, -248, -236, -224, -212, -199, -187, -175, -162, -150, -137, -125, -112, -100, -87, -75, -62, -50, -37, -25, -12
  32. };
  33.  
  34. uint8 far *image = (uint8 far *)0xB8000000L;
  35. uint16 ptr;
  36.  
  37. uint8 pass = 0, frameupdate;
  38.  
  39. void interrupt far (*old_timer)();
  40.  
  41. static void interrupt timer_isr() {
  42.     frameupdate = 1;
  43.     pass = (pass + 1) % 2; //we've doubled the rate of the PIT, so only pass back to the original
  44.     if (pass==0) old_timer(); //handler on every OTHER tick, or the system clock increments twice as fast
  45.         else outportb(0x20, 0x20); //if we don't go back to the original handler, we need to signal EOI ourself
  46. }
  47.  
  48. int main()
  49. {
  50.   uint16 i,j,newfreq,oldseg,oldptr;
  51.   uint8 index, cc;
  52.   int x;
  53.  
  54.   asm {
  55.       mov ax, 0x0003
  56.       int 10h
  57.   }
  58.  
  59.   oldptr = peek(0, 8*4);
  60.   oldseg = peek(0, 8*4+2);
  61.   old_timer = (void far *)((uint32)oldptr | ((uint32)oldseg << 16));
  62.   asm {
  63.       pushf
  64.       cli
  65.   }
  66.   poke(0, 8*4, &timer_isr);
  67.   poke(0, 8*4+2, _CS);
  68.   asm popf;
  69.  
  70.   //double the system timer chip's normal rate to keep us limited to about 36.4 FPS
  71.   newfreq = 32768;
  72.   outportb(0x43, 0x36);
  73.   outportb(0x40, newfreq & 0xFF);
  74.   outportb(0x40, newfreq >> 8);
  75.  
  76.   while(!kbhit())
  77.     {
  78.       frameupdate = 0;
  79.       tpos4 = pos4;
  80.       tpos3 = pos3;
  81.  
  82.       ptr = 0;
  83.       for (i = 0; i < SCREEN_HEIGHT; ++i)
  84.         {
  85.           tpos1 = pos1 + 3;
  86.           tpos2 = pos2 + 1;
  87.          
  88.           tpos3 &= 511;
  89.           tpos4 &= 511;
  90.          
  91.           for (j = 0; j < SCREEN_WIDTH; ++j)
  92.             {
  93.               tpos1 &= 511;
  94.               tpos2 &= 511;
  95.              
  96.               x = sintab[tpos1] + sintab[tpos2] + sintab[tpos3] + sintab[tpos4];
  97.              
  98.               index = 128 + (x >> 4);
  99.  
  100.               switch (index>>6) {
  101.                   case 0:
  102.                     cc = 176;
  103.                     break;
  104.                   case 1:
  105.                     cc = 177;
  106.                     break;
  107.                   case 2:
  108.                     cc = 178;
  109.                     break;
  110.                   case 3:
  111.                     cc = 219;
  112.                     break;
  113.               }
  114.              
  115.               image[ptr++] = cc;
  116.               image[ptr++] = index >> 4;
  117.  
  118.               tpos1 += 3;
  119.               tpos2 += 1;
  120.             }
  121.          
  122.           tpos4 += 3;
  123.           tpos3 += 1;
  124.         }
  125.  
  126.       //move plasma
  127.       pos1 +=3;
  128.       pos3 +=1;
  129.      
  130.       while (!frameupdate) { }
  131.  
  132.     }
  133.     getch();
  134.  
  135.   asm {
  136.       mov ax, 0x0003
  137.       int 10h
  138.   }
  139.  
  140.   //restore the original 18.2 Hz of the timer
  141.   newfreq = 0; //the PIT interprets 0 as 65536
  142.   outportb(0x43, 0x36);
  143.   outportb(0x40, (uint16)(newfreq & 0xFF));
  144.   outportb(0x40, (uint16)(newfreq >> 8));
  145.  
  146.   asm {
  147.       pushf
  148.       cli
  149.   }
  150.   poke(0, 8*4, oldptr);
  151.   poke(0, 8*4+2, oldseg);
  152.   asm popf;
  153.  
  154.   return 0;
  155. }