Nowadays we take so many things for granted. This isn't necessarily a bad thing, as knowing that performing a certain task will usually yield the same result can be a blessing. Nevertheless, some basic knowledge of how a thing gets done lets you better understand the world in which we live. Therefore, today I invite anyone who likes to code in any of the popular languages to see how a word gets printed out on the console screen.
Video Memory Programming in Text Mode - The code (Page 3 of 4 )
The current operating systems do not allow this kind of low level access to the video card. In order to allow this, we need to use an environment that grants us that access. The Turbo C or the Borland C 3.1 development IDE allow this. First you will need to acquire such a thing. A few Google searches should definitely reveal a couple of sources. Furthermore, these are 16-bit programs.
Because the Windows operating system's backward compatibility is only one step long, you cannot run these programs on a 64-bit operating system. If you are in this situation, to try out this code you will need to install a 32-bit operating system. In order to make the task of installing a new operating system a little easier, you may use a virtualization method like the one presented by the VMware Player or the Windows virtualization system.
Once you have a development environment like the Borland Turbo C++ 3.0 up and running, you can create a new file and use the pokeb function to write data to the video memory. Defined in the dos.h header, this function will store a byte value at the memory location and the offset specified. With the following formula: (80*y+x)*2 we can calculate the offset of a character in row y and column x. Now we can start up and just use the following code:
#include <dos.h>
#include <time.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int uint;
typedef unsigned char uchar;
void clear () // clear the screen -> black bg and fg
{
uint x, y;
uint offset;
for (x=0; x<80; ++x)
for (y=0; y<25; ++y)
{
offset = (80*y + x)*2;
pokeb (0xB800, offset, 0);
pokeb (0xB800, offset+1, 0);
}
}
// Put a character in the x-th row y-th column
// The attributes are inside a and the character is c
void putXY (uint x, uint y, uchar c, uchar a)
{
uint offset;
if (x<80 && y<25)
{
offset = (80*y + x)*2;
pokeb (0xB800, offset, c);
pokeb (0xB800, offset+1, a);
}
}
// Put the text(s) in l-th row with attributes a
void putLine (uint l, uchar *s, uchar a)
{
uint i;
for (i=0; s[i]; ++i)
putXY (i, l, s[i], a);
}
//Print a file text. Attributes are random. Stop per screen.
void putFileText (char *fname)
{
FILE *f;
char s [80];
uint l;
uchar a=15;
randomize (); // to get truly random attributes
f = fopen (fname, "r"); // open file
if (f == NULL)
return;
for (l=0; !feof (f); ++l) // until we have from file
{
do {// avoid same foreground and background colors
a = random (256);
} while ((a & 0XF0)>>4 == (a & 0X0F));
fgets(s, 80, f); //get item and print
putLine (l, (uchar*) s, a);
if (l==24) // when the screen is full, clear and wait
{
getch ();
clear ();
l=-1; //reset to start
}
}
fclose (f); //close the file
}
//Fill the background with the attribute, use space chars