Change VGA Font Bitmap

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
arabasso
Member
Member
Posts: 27
Joined: Thu Jul 10, 2008 9:41 am

Change VGA Font Bitmap

Post by arabasso »

Hello everyone.

I'm having trouble changing the font bitmap from VGA card. I am developing a 32-bit paging kernel for the x86 architecture. Following is the code:

Code: Select all

static void set_plane(unsigned p)
{
	unsigned char pmask;

	p &= 3;
	pmask = 1 << p;

	outportb(0x3CE, 4);
	outportb(0x3CF, p);

	outportb(0x3C4, 2);
	outportb(0x3C5, pmask);
}

static void write_font(unsigned char *buf)
{
	unsigned char seq2, seq4, gc4, gc5, gc6;
	unsigned font_height, i, j;
	unsigned char * ptr;

	outportb(0x3C4, 2);
	seq2 = inportb(0x3C5);

	outportb(0x3C4, 4);
	seq4 = inportb(0x3C5);

	outportb(0x3C5, seq4 | 0x04);

	outportb(0x3CE, 4);
	gc4 = inportb(0x3CF);

	outportb(0x3CE, 5);
	gc5 = inportb(0x3CF);

	outportb(0x3CF, gc5 & ~0x10);

	outportb(0x3CE, 6);
	gc6 = inportb(0x3CF);

	outportb(0x3CF, gc6 & ~0x02);

	set_plane(2);

	font_height = 16;

	ptr = (unsigned char *) 0xB8000;

	for(i = 0; i < 256; i++)
	{
		for(j = 0; j < font_height; j++)
		{
			ptr[0x1000 + 32 * i + j] = buf[font_height * i + j];
		}
	}

	outportb(0x3C4, 2);
	outportb(0x3C5, seq2);
	outportb(0x3C4, 4);
	outportb(0x3C5, seq4);
	outportb(0x3CE, 4);
	outportb(0x3CF, gc4);
	outportb(0x3CE, 5);
	outportb(0x3CF, gc5);
	outportb(0x3CE, 6);
	outportb(0x3CF, gc6);
}
This code runs normally, but nothing happens. I even pulled the first character to finally added to the letters scrambled stayed, but when I write something on the screen nothing happens.

Does anyone know what could it be?
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Change VGA Font Bitmap

Post by egos »

Look at New fonts.

Try

Code: Select all

  outportb(0x3C5, 0x04);
instead of

Code: Select all

  outportb(0x3C5, seq4 | 0x04);
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
Creature
Member
Member
Posts: 548
Joined: Sat Dec 27, 2008 2:34 pm
Location: Belgium

Re: Change VGA Font Bitmap

Post by Creature »

Are you sure that you've identity mapped whatever video memory address you're using? I know I forgot that when I tried VGA programming once, it took me weeks to find out that I hadn't identity mapped video memory, all my other code was perfectly fine. But usually the VGA memory addresses are all under 1 MB, which you should identity map anyways (I think), I had some special address above 1 MB which made it necessary to identity map it myself.
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Change VGA Font Bitmap

Post by egos »

Try

Code: Select all

  ptr[32 * i + j] = buf[font_height * i + j];
instead of

Code: Select all

ptr[0x1000 + 32 * i + j] = buf[font_height * i + j];
Why you use the 0x1000 item? It's middle position for bitmap 0. In this case you would load only last 128 glyphs (for characters with codes 0x80-0xFF). Additionally, there's a probability that the frame address for fixing VRAM is other than 0xB8000. To force a setting this address set bits 2 and 3 of miscellaneous graphics register (graph[0x06]) to 11b.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
arabasso
Member
Member
Posts: 27
Joined: Thu Jul 10, 2008 9:41 am

Re: Change VGA Font Bitmap

Post by arabasso »

Thanks for posts.

I managed to map a new VGA font bitmap with the following code:

Code: Select all

#define VGA_GFX_REG				0x3CE
#define VGA_SEQ_REG				0x3C4
#define VGA_CRT_REG				0x3D4

#define VGA_GFX_I_RESET			0x00
#define VGA_GFX_I_ENABLE		0x01
#define VGA_GFX_I_COLORCMP		0x02
#define VGA_GFX_I_ROTATE		0x03
#define VGA_GFX_I_READMAP		0x04
#define VGA_GFX_I_MODE			0x05
#define VGA_GFX_I_MISC			0x06
#define VGA_GFX_I_CNOCARE		0x07
#define VGA_GFX_I_BITMASK		0x08

#define VGA_SEQ_I_RESET			0x00
#define VGA_SEQ_I_CLOCK			0x01
#define VGA_SEQ_I_MAPMASK		0x02
#define VGA_SEQ_I_CHARMAP		0x03
#define VGA_SEQ_I_MEMMODE		0x04

unsigned char readRegVGA(unsigned short reg, unsigned char idx)
{
	outb(reg, idx);

	return inb(reg + 0x01);
}

void writeRegVGA(unsigned short reg, unsigned char idx, unsigned char val)
{
	outb(reg, idx);
	outb(reg + 1, val);
}

void setFontVGA(const unsigned char * buffer, int h)
{
	unsigned char seq2, seq4, gfx6;
	int i, j;
	unsigned char * mem;

	seq2 = readRegVGA(VGA_SEQ_REG, VGA_SEQ_I_MAPMASK);
	writeRegVGA(VGA_SEQ_REG, VGA_SEQ_I_MAPMASK, 0x04);

	seq4 = readRegVGA(VGA_SEQ_REG, VGA_SEQ_I_MEMMODE);
	writeRegVGA(VGA_SEQ_REG, VGA_SEQ_I_MEMMODE, 0x06);

	writeRegVGA(VGA_SEQ_REG, VGA_SEQ_I_CHARMAP, 0x00);

	gfx6 = readRegVGA(VGA_GFX_REG, VGA_GFX_I_MISC);
	writeRegVGA(VGA_SEQ_REG, VGA_GFX_I_MISC, 0x00);

	mem = (unsigned char *) 0xB0000;

	for (i = 0; i < 256; i++)
	{
		for (j = 0; j < h; j++)
			mem[j] = buffer[h * i + j];

		mem += 32;
	}

	writeRegVGA(VGA_GFX_REG, VGA_GFX_I_MISC, gfx6);
	writeRegVGA(VGA_SEQ_REG, VGA_SEQ_I_MEMMODE, seq4);
	writeRegVGA(VGA_SEQ_REG, VGA_SEQ_I_MAPMASK, seq2);

	writeRegVGA(VGA_GFX_REG, VGA_GFX_I_MODE, 0x10);
	writeRegVGA(VGA_GFX_REG, VGA_GFX_I_BITMASK, 0xFF);
}
The strange thing is that both the address 0xB0000 and 0xA0000 remaps the font bitmap. Another thing about this code: it works well on bochs, qemu and the real PC, but not in wmware. I've seen in many places there are a range of problems in vmware VGA. Does anyone know a fix for the problem of VGA in vmware? Or just right is to a specific driver for it?
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Change VGA Font Bitmap

Post by egos »

It is not problem of VMWare. You would use VGA specification and its agreements. And exactly when you specify the address 0xA0000 for fixing VRAM by setting graph[0x06] to zero, you would use this one.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
arabasso
Member
Member
Posts: 27
Joined: Thu Jul 10, 2008 9:41 am

Re: Change VGA Font Bitmap

Post by arabasso »

Why?

I did not understand what you mean about the VGA vmware. I assume that the real PC and other emulators everything is working OK, then the problem is with vmware. Or not?

I'm using the 0xA0000 base address for setting VGA font, but vmware does not work in any way.

if you know how to solve this, could you be more specific?
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Change VGA Font Bitmap

Post by egos »

arabasso wrote:I'm using the 0xA0000 base address for setting VGA font, but vmware does not work in any way.
I couldn't see this in your code.

Code: Select all

   mem = (unsigned char *) 0xB0000;
arabasso wrote:if you know how to solve this, could you be more specific?
In last code fragment you missed one thing. I gave the link here.
I wrote:Font loading:
graph[0x05] = 0x00 (bit 4 = 0)
graph[0x06] = 0x0C (bit 1 = 0) ; 0 for 0xA0000
seq[0x02] = 0x04 (0100b)
seq[0x04] = 0x06/0x07 (bit 2 = 1)

Characters and attributes writing (normal mode):
graph[0x05] = 0x10 (bit 4 = 1)
graph[0x06] = 0x0E (bit 1 = 1) ; 2 for 0xA0000
seq[0x02] = 0x03 (0011b)
seq[0x04] = 0x02/0x03 (bit 2 = 0)
If you have seen bad English in my words, tell me what's wrong, please.
Post Reply