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