I decided to build off of the Assembly example demonstrated here to show the same basic program written in a higher-level language. This program will make the same sprawling palette, then fade it out to black. The program was written in Turbo C++ 1.01, which is available for free under Borlands Antique Software Museum.
//dos.h is used to for the interupt calling functions, registers structure,
//and for input/output functions
#include < dos.h >
int main()
{
//Used to store the palette entries. This could have easily
//been done as a 3 dimensional array, but I feel conceptually
//it is easier to use 3 seperate arrays for red, blue, and green
unsigned char red[256], blue[256], green[256];
//A far pointer used to work directly with the VGA screen memory
//unsigned char far *VGA = (unsigned char *)MK_FP(0xA000, 0); //alternate declaration
unsigned char far *VGA = (unsigned char *) 0xA0000000L;
//counters, make sure they are unsigned
unsigned int x, y, z;
//used to represent the CPU registers, provided by dos.h
union REGS regs;
//set the registers for Interupt 10h, function 0, mode 13h
//and call the interrupt to set the video mode to 320x200 256 colors
regs.h.ah = 0;
regs.h.al = 0x13;
int86(0x10, ®s, ®s);
//load the sprawling palette onto the screen
for (x = 0; x < 200; x++)
for (y = 0; y < 320; y++)
//since the palette is only 256 colors, loop back
//to the first color after 320
if (y < 256)
VGA[(x * 320) + y] = y;
else
VGA[(x * 320) + y] = y - 320;
//Now load the palette into memory. This will allow
//us to manipulate the palette in memory and load into
//the palette rather than having to read, change, then write
//from the video ports
for (x = 0; x < 255; x++)
{
//port 3c7 signals palette read from port 3c9
outp(0x3c7, x);
red[x] = inp(0x3c9);
green[x] = inp(0x3c9);
blue[x] = inp(0x3c9);
}
//What this will do is fade red out first, then blue, then green
//X controls which color is fading, y controls the intensity, and
//z is controlling which palette entry we are changing
for (x = 0; x < 3; x++)
for (y = 0; y < 64; y++)
for (z = 1; z < 255; z++)
{
//based on the color to fade, subtract that color
switch (x)
{
case 0:
if (red[z] > 0)
red[z]--;
break;
case 1:
if (green[z] > 0)
green[z]--;
break;
case 2:
if (blue[z] > 0)
blue[z]--;
break;
} //end switch
//port 3c8 signals 3c9 to recieve a new palette
//entry for color z
outp(0x3c8, z);
outp(0x3c9, red[z]);
outp(0x3c9, green[z]);
outp(0x3c9, blue[z]);
} //end for
//switch screen mode back to 80x25 text
regs.h.ah = 0;
regs.h.al = 0x3;
int86(0x10, ®s, ®s);
return 0;
}
The program touches on a few interesting points. It demonstrates how to communicate with hardware ports using the old DOS architecture and Turbo C++. It also demonstrates how pointers can be used to directly access hardware memory points, such as the VGA memory. It also demonstrates how to call DOS and hardware interrupts in a higher-level language using the dos.h header file. Something like this could have been written in assembler, however it would have been very difficult. In my next article, I will show how C++ and inline assembly can be used to accomplish the same task.
Subscribe to:
Post Comments (Atom)
2 comments:
can i control the external fan or bulb by c/c++ prog..i.e on or off..
if yes then help me..
vkgupta2807@gmail.com
Yes. Its pretty easy to do. With an old school DOS program like this, your basically just going to write out the parallel port to trigger a simple switch circuit that is either powered by a relay or a transistor. If its done with a transistor, the input from your parallel port is going into the base. Plenty of documentation on using a transistor as a switch out there.
Post a Comment