How do I output to the text screen?

Working on the assumption that you are in protected mode and not using the BIOS to do screen writes, you will have to do screen writes direct to "video" memory yourself.

This is quite easy to do, the text screen video memory for colour monitors resides at 0xB8000, and for monochrome monitors it is at address 0xB0000.

Text mode memory takes two bytes for every "character" on the screen. It consists of a colour byte and an actual ASCII value. so ABCD is stored as

'A', colourforA
'B', colourforB
'C', colourforC
'D', colourforD

For colour video cards, you have 16kb of text video memory to use, and since 80x25 mode (80x25x2==4000 bytes per screen) does not use all 16kb, you have what is known as 'pages' and in 80x25 screen mode you have 8 display pages to use.

When you print to any other page than 0, it will not appear on screen until that page is "enabled" or "copied" into the page 0 memory space.

If you have a pointer to video memory and want to write a string, here is how you might do it;


	/* note this example will always write to the top
	   line of the screen */
	void write_string(int colour, char *string)
	{
		char *video=(char*)0xB8000;
		while(*string!=0)
		{
			*video=*string;
			string++;
			video++;
			*video=colour;
			video++;
		}
	}
		

 

How do I detect if I have a colour or monochrome video card?

Detecting if you have a colour or monochrome video card is trivial. You can use the values stored in the BIOS data segment to determine this.

Here is some C source example of how I do it.


	/* video card mono/colour detection by Dark Fiber
	 * returns 0=mono, 1=colour
	 */
	int detect_video_type(void)
	{
		int rc;
		char c=(*(USHORT*)0x410&0x30

		/* C can be 0x00 or 0x20 for colour, 0x30 for mono
		if(c==0x30)
			rc=0;	// mono
		else
			rc=1;	// colour

		return rc;
	}
        

 

How do I move the cursor when I print?

Without access to bios calls and functions, moving the cursor requires using video hardware control. Lucky for us it is a simple procedure.

Note, this quick example ASSUMES 80x25 screen mode.


	/* void update_cursor(int row, int col)
	 * by Dark Fiber
	 */
	void update_cursor(int row, int col)
	{
		USHORT	position=(row*80) + col;

		// cursor LOW port to vga INDEX register
		outb(0x3D4, 0x0F);
		outb(0x3D5, (UCHAR)(position&0xFF));
		// cursor HIGH port to vga INDEX register
		outb(0x3D4, 0x0E);
		outb(0x3D5, (UCHAR)((position>>8)&0xFF));
	}