#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;
}