Problem setting vesa text mode

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.
User avatar
gzaloprgm
Member
Member
Posts: 141
Joined: Sun Sep 23, 2007 4:53 pm
Location: Buenos Aires, Argentina
Contact:

Problem setting vesa text mode

Post by gzaloprgm »

Hi, I'm having a problem with setting a vesa mode on my 16-bit bootloader.

My code is the following:

Code: Select all

mov ax, 4F02h
mov bx,108h
int 10h
It should switch to 80*60 mode but it doesn't do anything. I tried with bochs, qemu and virtual box.

Can anyone tell me what am I doing wrong?

Thanks,
Gonzalo
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

I think you got the mode number wrong.
In standard VESA resolutions, mode 108h is graph 1280x1024 256 colors and mode 109h is text 80x60. ;)
However, with VESA/VBE 2.0 and above you should not count on it being available. You should always check the video modes supported using tha appropriate function.

Note: Newer video boards don't support any VESA text modes (that might also be your case). You could always use VGA mode 80x50, though. It's guaranteed to work.

Cheers,
Gabriel
User avatar
gzaloprgm
Member
Member
Posts: 141
Joined: Sun Sep 23, 2007 4:53 pm
Location: Buenos Aires, Argentina
Contact:

Post by gzaloprgm »

Thanks for answering my question.

So I guess if I wanna make a big console I'll have to switch to a vesa graphic mode and write to the screen with a bitmap font.

Cheers,
Gonzalo
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

Thats what i do, i have a shell in 1024x768x32bpp :)
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
Philip
Member
Member
Posts: 59
Joined: Thu Mar 06, 2008 11:37 pm
Location: Singapore

Post by Philip »

it's terrible to make a bitmap font yourself, quite a long tiring job
User avatar
gzaloprgm
Member
Member
Posts: 141
Joined: Sun Sep 23, 2007 4:53 pm
Location: Buenos Aires, Argentina
Contact:

Post by gzaloprgm »

Not necessarily.

You can make a simple bitmap font in less than an hour, but if you want a good font you'll obviously have to spend more time on it.

Cheers,
Gonzalo
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

gzaloprgm wrote:So I guess if I wanna make a big console I'll have to switch to a vesa graphic mode and write to the screen with a bitmap font.
Not necessarily. Standard VGA supports up to 90x60. You can set this mode by setting a number of VGA registers. It works on real hardware and Bochs, although I think VMWare doesn't like it. Haven't tried it on Qemu yet. Next, you'll have to set an 8x8 font.

The attachment has some code to achieve this. I don't have time to make dedicated routines, but it's somewhere near the bottom. Note that I took the font data (font.cpp) from DOSbox, which is GPLed, but no doubt they just dumped it from whatever video card they used, so I doubt the GPL really holds on that one.

If I have time, I'll maybe write a Wiki entry about setting the 90x60, if anyone would like.


JAL
Attachments
Video.cpp
code for setting 90x60 textmode
(9.19 KiB) Downloaded 330 times
font.cpp
8x8 textmode bitmap font
(12.57 KiB) Downloaded 282 times
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

I think it would be beneficial if it was contributed to the wiki, chances are somebody will find it useful, and additional information is always useful :)
~ Lukem95 [ Cake ]
Release: 0.08b
Image
User avatar
gzaloprgm
Member
Member
Posts: 141
Joined: Sun Sep 23, 2007 4:53 pm
Location: Buenos Aires, Argentina
Contact:

Post by gzaloprgm »

Lots of Thanks Jal!!!

With this code the 90*60 mode worked perfectly.

Code: Select all

unsigned int Regs[] = {0x6900, 0x5901, 0x5a02, 0x8c03, 0x5e04, 0x8a05, 0x0b06, 0x3e07, 0x4709, 0xea10, 0x8c11, 0xdf12, 0x2d13, 0xe715, 0x0416};
outportw(0x3c4, 0x100);
outportb(0x3c2, 0xe7);
outportw(0x3c4, 0x0300);
outportw(0x3c4, 0x0000);
outportw(0x3c4, 0x0101);
outportw(0x3c4, 0x0300);
outportw(0x3d4, 0x0e11);
int i;
for ( i = 0; i < 15; i++){
	outportw(0x3d4, Regs[i]);
}
inportb(0x3da);
outportb(0x3c0, 0x33);
outportb(0x3c0, 0x00);
I dont need to set a font because in my bootloader I set 8x8 font and 80*50 mode.
jal wrote:It works on real hardware and Bochs, although I think VMWare doesn't like it. Haven't tried it on Qemu yet.
In my case it worked in Qemu, Bochs, VirtualBox and real Hardware :D

Cheers,
Gonzalo
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

lukem95 wrote:I think it would be beneficial if it was contributed to the wiki, chances are somebody will find it useful, and additional information is always useful :)
Yeah, I'll see if I can find some time this week. Must also try to explain, that array with port values is nice, but one perhaps likes to know what it does :). Time to get Ferraro out...


JAL
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Post by jal »

gzaloprgm wrote:With this code the 90*60 mode worked perfectly.
Glad to hear it!
I dont need to set a font because in my bootloader I set 8x8 font and 80*50 mode.
You're right, it's not needed then. I use Grub, so I must set it in protected mode the hard way.


JAL
trolly
Member
Member
Posts: 52
Joined: Tue Mar 25, 2008 12:26 pm

Post by trolly »

I dont need to set a font because in my bootloader I set 8x8 font and 80*50 mode.
how did it set the 8x8 font?
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

gzaloprgm wrote:Lots of Thanks Jal!!!

With this code the 90*60 mode worked perfectly.

Code: Select all

unsigned int Regs[] = {0x6900, 0x5901, 0x5a02, 0x8c03, 0x5e04, 0x8a05, 0x0b06, 0x3e07, 0x4709, 0xea10, 0x8c11, 0xdf12, 0x2d13, 0xe715, 0x0416};
outportw(0x3c4, 0x100);
outportb(0x3c2, 0xe7);
outportw(0x3c4, 0x0300);
outportw(0x3c4, 0x0000);
outportw(0x3c4, 0x0101);
outportw(0x3c4, 0x0300);
outportw(0x3d4, 0x0e11);
int i;
for ( i = 0; i < 15; i++){
	outportw(0x3d4, Regs[i]);
}
inportb(0x3da);
outportb(0x3c0, 0x33);
outportb(0x3c0, 0x00);
I dont need to set a font because in my bootloader I set 8x8 font and 80*50 mode.
jal wrote:It works on real hardware and Bochs, although I think VMWare doesn't like it. Haven't tried it on Qemu yet.
In my case it worked in Qemu, Bochs, VirtualBox and real Hardware :D

Cheers,
Gonzalo
I just use mode 0x1112, 80x50, it's much simpler to set (just an interrupt call), so it saves me space in my bootloader ;).

mov ax, 0x1112
xor bx, bx
int 0x10

I also get rid of the cursor cause I don't like it, but that's another story :)
mov word [0x60], 0x07 ;Just incase you wanted to know how

I do this before entering pmode in my bootloader, so any information displayed from then forward is not lost (until I either clear the screen manually, scroll the screen with to much data, or switch modes).
User avatar
Stevo14
Member
Member
Posts: 179
Joined: Fri Mar 07, 2008 3:40 am
Location: Arad, Romania

Post by Stevo14 »

jal wrote:Must also try to explain, that array with port values is nice, but one perhaps likes to know what it does :). Time to get Ferraro out...
Already done. :)
Here is the code with the values moved out of the array. IMHO it is easer to read and easier to use as a learning tool.

EDIT: Updated code

Code: Select all

void set_small_font()
{
	int line_height = 8;//8 pixels high characters

	outportb(SEQ_ADDR, SEQ_I_MAPMASK);
	unsigned char org_mapmask = inportb(SEQ_DATA);
	outportb(SEQ_DATA, 0x04);	//(0100) select plane 2 (the font plane)

	outportb(SEQ_ADDR, SEQ_I_MEMMODE);
	unsigned char org_memmode = inportb(SEQ_DATA);
	outportb(SEQ_DATA , 0x06);

	outportb(SEQ_ADDR, SEQ_I_CHARMAP);
	outportb(SEQ_DATA, 0x00);	//(000000) font a and b are mapped to zero (the first font)

	outportb(GFX_ADDR, GFX_I_MISC); 
	unsigned char org_gfx = inportb(GFX_DATA);
	outportb(GFX_ADDR, GFX_I_MISC); 
	outportb(GFX_DATA, 0x00); 	//(0000) disable odd/even

	unsigned char *pVidMem = (unsigned char*)0xA0000;
	int i,j = 0;

	for (i = 0; i < 256; i++)
	{
		for (j = 0; j < line_height; j++)
		{
			*(pVidMem + j) = 0x00;//clear it first
			*(pVidMem + j) = smallfont[i*8+j];//then set the value
		}
		pVidMem += 32;
	}

	outportb(SEQ_ADDR, SEQ_I_MEMMODE);
	outportb(SEQ_DATA , org_memmode);

	outportb(SEQ_ADDR, SEQ_I_MAPMASK);
	outportb(SEQ_DATA , org_mapmask);

	outportb(GFX_ADDR, GFX_I_MISC); //restore the old gfx misc settings
	outportb(GFX_DATA, org_gfx);

	outportb(GFX_ADDR, GFX_I_MODE);
	outportb(GFX_DATA, 0x10);

	outportb(GFX_ADDR, GFX_I_BITMASK);
	outportb(GFX_DATA, 0xFF);

}

void set90x60()
{
	int i = 0;

	set_small_font();	

	outportb(SEQ_ADDR, SEQ_I_RESET);//asynchronously clear and halt.
	outportb(SEQ_DATA, 0x01);

		outportb(VGA_MISC_W, 0xE7);//set part of the clock data through the misc regester

	outportb(SEQ_ADDR, SEQ_I_RESET);//continue operation
	outportb(SEQ_DATA, 0x03);

	outportb(SEQ_ADDR, SEQ_I_RESET);//synchronously clear and halt
	outportb(SEQ_DATA, 0x02);

		outportb(SEQ_ADDR, SEQ_I_CLOCK);
		outportb(SEQ_DATA, 0x01);//(8 dot wide characters)

	outportb(SEQ_ADDR, SEQ_I_RESET);//continue operation
	outportb(SEQ_DATA, 0x03);

	outportb(CRT_ADDR, CRT_I_END_V_RET); 
	outportb(CRT_DATA, 0x0E);

	outportb(CRT_ADDR, CRT_I_H_TOTAL); 
	outportb(CRT_DATA, 0x6B);

	outportb(CRT_ADDR, CRT_I_END_H_DIS);
	outportb(CRT_DATA, 0x59);//(89) the number of characters wide - 1

	outportb(CRT_ADDR, CRT_I_START_H_BLANK);
	outportb(CRT_DATA, 0x5A);

	outportb(CRT_ADDR, CRT_I_END_H_BALNK);
	outportb(CRT_DATA, 0x82);

	outportb(CRT_ADDR, CRT_I_START_H_RET);
	outportb(CRT_DATA, 0x60);

	outportb(CRT_ADDR, CRT_I_END_H_RET);
	outportb(CRT_DATA, 0x8D);

	outportb(CRT_ADDR, CRT_I_V_TOTAL); 
	outportb(CRT_DATA, 0x0B);

	outportb(CRT_ADDR, CRT_I_OVERFLOW); 
	outportb(CRT_DATA, 0x3E);

	outportb(CRT_ADDR, CRT_I_PRE_ROW_SCN); 
	outportb(CRT_DATA, 0x00);

	outportb(CRT_ADDR, CRT_I_MAX_SCN_LINE);
	outportb(CRT_DATA, 0x47);

	outportb(CRT_ADDR, CRT_I_START_V_RET);
	outportb(CRT_DATA, 0xEA);

	outportb(CRT_ADDR, CRT_I_END_V_RET);
	outportb(CRT_DATA, 0x0C);

	outportb(CRT_ADDR, CRT_I_END_V_DIS);
	outportb(CRT_DATA, 0xDF);

	outportb(CRT_ADDR, CRT_I_OFFSET);
	outportb(CRT_DATA, 0x2D);

	outportb(CRT_ADDR, CRT_I_UND_LOC);
	outportb(CRT_DATA, 0x08);

	outportb(CRT_ADDR, CRT_I_START_V_BLANK);
	outportb(CRT_DATA, 0xE8);

	outportb(CRT_ADDR, CRT_I_END_V_BLANK);
	outportb(CRT_DATA, 0x05);

	outportb(CRT_ADDR, CRT_I_MODE);
	outportb(CRT_DATA, 0xA3);

	outportb(CRT_ADDR, CRT_I_LINE_CMP);
	outportb(CRT_DATA, 0xFF);

	width = 90;
	height = 60;
}
Some of the comments may be wrong. Especially the part near the beginning with all the set/reset stuff on the sequencer.

EDIT: Comments are now fine.

And here is the #define section

Code: Select all

#define GFX_ADDR			0x3CE
#define GFX_DATA			0x3CF
#define GFX_I_RESET		0x00
#define GFX_I_ENABLE		0x01
#define GFX_I_COLORCMP	0x02
#define GFX_I_ROTATE		0x03
#define GFX_I_READMAP	0x04
#define GFX_I_MODE		0x05
#define GFX_I_MISC		0x06
#define GFX_I_CNOCARE	0x07
#define GFX_I_BITMASK	0x08

#define SEQ_ADDR 			0x3C4
#define SEQ_DATA 			0x3C5
#define SEQ_I_RESET 		0x00
#define SEQ_I_CLOCK 		0x01
#define SEQ_I_MAPMASK 	0x02
#define SEQ_I_CHARMAP	0x03
#define SEQ_I_MEMMODE	0x04

#define ATR_ADDR_DATA	0x3C0
#define ATR_DATA_READ	0x3C1

#define CRT_ADDR					0x3D4
#define CRT_DATA					0x3D5
#define CRT_I_H_TOTAL			0x00
#define CRT_I_END_H_DIS 		0x01
#define CRT_I_START_H_BLANK 	0x02
#define CRT_I_END_H_BALNK	 	0x03
#define CRT_I_START_H_RET 		0x04
#define CRT_I_END_H_RET 		0x05
#define CRT_I_V_TOTAL 			0x06
#define CRT_I_OVERFLOW 			0x07
#define CRT_I_PRE_ROW_SCN	 	0x08
#define CRT_I_MAX_SCN_LINE 	0x09
#define CRT_I_START_CUR 		0x0A
#define CRT_I_END_CUR 			0x0B
#define CRT_I_START_ADDR_H 	0x0C
#define CRT_I_START_ADDR_L 	0x0D
#define CRT_I_CUR_LOC_H 		0x0E
#define CRT_I_CUR_LOC_L 		0x0F
#define CRT_I_START_V_RET 		0x10
#define CRT_I_END_V_RET 		0x11
#define CRT_I_END_V_DIS 		0x12
#define CRT_I_OFFSET 			0x13
#define CRT_I_UND_LOC 			0x14
#define CRT_I_START_V_BLANK 	0x15
#define CRT_I_END_V_BLANK 		0x16
#define CRT_I_MODE 				0x17
#define CRT_I_LINE_CMP 			0x18

#define DAC_ADDR_W		0x3C8
#define DAC_ADDR_R		0x3C7
#define DAC_DATA			0x3C9
#define DAC_STATE			0x3C7

#define VGA_MISC_W		0x3C2
#define VGA_MISC_R		0x3CC
#define VGA_FEATURE_W	0x3DA
#define VGA_FEATURE_R	0x3CA
#define VGA_STATUS_0		0x3C2
#define VGA_STATUS_1		0x3DA
Last edited by Stevo14 on Thu Mar 27, 2008 7:23 am, edited 1 time in total.
User avatar
gzaloprgm
Member
Member
Posts: 141
Joined: Sun Sep 23, 2007 4:53 pm
Location: Buenos Aires, Argentina
Contact:

Post by gzaloprgm »

trolly wrote:
I dont need to set a font because in my bootloader I set 8x8 font and 80*50 mode.
how did it set the 8x8 font?

Code: Select all

mov ax,1112h ;Function 1112
xor bl,bl ;BL - 8x8 font 
int 10h

mov ah,01 ;Function 1: change cursor
mov cx,0x06FF ;Starting sline: 6h, ending ffh
int 10h	
Cheers,
Gonzalo
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
Post Reply