#define uint8 unsigned char #define int8 char #define uint16 unsigned short #define int16 short #define uint32 unsigned long #define int32 long #define uint64 unsigned long long #define int64 long long #define SCREEN_WIDTH 80 #define SCREEN_HEIGHT 25 static uint16 pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0, tpos1, tpos2, tpos3, tpos4; static int sintab[512] = { 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, 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, 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, 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, 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, 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, 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, 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, -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, -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, -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, -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, -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, -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, -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, -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 }; uint8 far *image = (uint8 far *)0xB8000000L; uint16 ptr; uint8 pass = 0, frameupdate; void interrupt far (*old_timer)(); static void interrupt timer_isr() { frameupdate = 1; pass = (pass + 1) % 2; //we've doubled the rate of the PIT, so only pass back to the original if (pass==0) old_timer(); //handler on every OTHER tick, or the system clock increments twice as fast else outportb(0x20, 0x20); //if we don't go back to the original handler, we need to signal EOI ourself } int main() { uint16 i,j,newfreq,oldseg,oldptr; uint8 index, cc; int x; asm { mov ax, 0x0003 int 10h } oldptr = peek(0, 8*4); oldseg = peek(0, 8*4+2); old_timer = (void far *)((uint32)oldptr | ((uint32)oldseg << 16)); asm { pushf cli } poke(0, 8*4, &timer_isr); poke(0, 8*4+2, _CS); asm popf; //double the system timer chip's normal rate to keep us limited to about 36.4 FPS newfreq = 32768; outportb(0x43, 0x36); outportb(0x40, newfreq & 0xFF); outportb(0x40, newfreq >> 8); while(!kbhit()) { frameupdate = 0; tpos4 = pos4; tpos3 = pos3; ptr = 0; for (i = 0; i < SCREEN_HEIGHT; ++i) { tpos1 = pos1 + 3; tpos2 = pos2 + 1; tpos3 &= 511; tpos4 &= 511; for (j = 0; j < SCREEN_WIDTH; ++j) { tpos1 &= 511; tpos2 &= 511; x = sintab[tpos1] + sintab[tpos2] + sintab[tpos3] + sintab[tpos4]; index = 128 + (x >> 4); switch (index>>6) { case 0: cc = 176; break; case 1: cc = 177; break; case 2: cc = 178; break; case 3: cc = 219; break; } image[ptr++] = cc; image[ptr++] = index >> 4; tpos1 += 3; tpos2 += 1; } tpos4 += 3; tpos3 += 1; } //move plasma pos1 +=3; pos3 +=1; while (!frameupdate) { } } getch(); asm { mov ax, 0x0003 int 10h } //restore the original 18.2 Hz of the timer newfreq = 0; //the PIT interprets 0 as 65536 outportb(0x43, 0x36); outportb(0x40, (uint16)(newfreq & 0xFF)); outportb(0x40, (uint16)(newfreq >> 8)); asm { pushf cli } poke(0, 8*4, oldptr); poke(0, 8*4+2, oldseg); asm popf; return 0; }