VBE higher resolution text modes support?

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.
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

VBE higher resolution text modes support?

Post by xeyes »

Was hoping to 'upgrade' to a higher resolution text mode than 80x25, and saw that VBE listed a few attractive options such as 10C and 10B.

However when I tried to scan for VBE modes in Qemu and Bochs, they do support many modes, but none of them seem to have any text mode :(

Like there's no mode in the range of 108 to 10C, and when I tested other modes with support bit set, all of them also had mode type bit (bit 4) set in the mode attributes.

Is it true that there's no support for any VBE text modes in the emulators despite the VBE spec listed possible ones?

Or maybe I didn't detect the modes correctly?
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: VBE higher resolution text modes support?

Post by Octocontrabass »

The VGA ROMs used by QEMU and Bochs don't support high-resolution text modes.

I'd be surprised if any of their emulated VGA hardware supports it. The "Cirrus SVGA" is based on a chip that was capable of high-resolution text, but it usually didn't include any VBE modes you could use to set it up.

You can get more rows out of ordinary VGA text mode: initialize the display with INT 0x10 AX=0x0003, then call INT 0x10 AX=0x1112 (BL=0x00) to select the 9x8 font, increasing the display to 50 rows. (There's also AX=0x1111 for the 9x14 font/28 rows, but that might not work on some hardware. If you're feeling really adventurous, set your own font with AX=0x1110.)
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: VBE higher resolution text modes support?

Post by xeyes »

Octocontrabass wrote:The VGA ROMs used by QEMU and Bochs don't support high-resolution text modes.

I'd be surprised if any of their emulated VGA hardware supports it. The "Cirrus SVGA" is based on a chip that was capable of high-resolution text, but it usually didn't include any VBE modes you could use to set it up.

You can get more rows out of ordinary VGA text mode: initialize the display with INT 0x10 AX=0x0003, then call INT 0x10 AX=0x1112 (BL=0x00) to select the 9x8 font, increasing the display to 50 rows. (There's also AX=0x1111 for the 9x14 font/28 rows, but that might not work on some hardware. If you're feeling really adventurous, set your own font with AX=0x1110.)
Thanks, 80x50 works but instead of propping the virtual display to be twice as tall, it squeezes all characters to be half height and thus managed to look worse than 80x25. Way less crisp, if that makes sense.

Drawing my own fonts sounds fun but also sounds like a lot of work, maybe something for another day.

I feel like maybe it would be a good idea to build a layer above the keyboard and "video" "drivers" that can optionally read/write a virtual serial port. Thus the host's terminal or putty can be used instead? But I'm afraid it might not be that simple and the terminal might send or expect complex control info besides characters that I'm typing or printing.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VBE higher resolution text modes support?

Post by bzt »

xeyes wrote:Thanks, 80x50 works but instead of propping the virtual display to be twice as tall, it squeezes all characters to be half height and thus managed to look worse than 80x25. Way less crisp, if that makes sense.
With overriding the VGA control registers, you can squeeze 90x60 out of a VGA video card (without using VESA).
xeyes wrote:Drawing my own fonts sounds fun but also sounds like a lot of work, maybe something for another day.
Not that difficult. Take a look at the wiki, there's a very-very simple example code on the VGA Fonts page (about 10 SLoC), a bit more optimized one on the PC Screen Font page (about 20 SLoC). Finally there's the dependency-free single header Scalable Screen Font library which provides a similar bitmap-only ssfn_putc() function (compiled size about 1K), and a more advanced ssfn_render() function which can scale, shape, kern glyphs and supports bitmap as well as scalable vector fonts too (total compiled size about 28K only).
xeyes wrote:I feel like maybe it would be a good idea to build a layer above the keyboard and "video" "drivers" that can optionally read/write a virtual serial port.
That's what Linux tty drivers are (not the ptty ones under X, but the plain tty ones, Ctrl+Alt+F1-F8). They used to be implemented with VGA text mode (good old days...), but these days they use graphical pixel-based modes and the aforementioned PC Screen Font format.
xeyes wrote:Thus the host's terminal or putty can be used instead? But I'm afraid it might not be that simple and the terminal might send or expect complex control info besides characters that I'm typing or printing.
Yes, they do send complex codes, but don't be frightened, here's a pretty comprehensive list of ANSI escape codes. For PuTTY, you can configure which sequences to send, and for Linux, it uses the termcap library, which has a human-readable "database" for the codes (under /etc/termcap), like

Code: Select all

ansi77|ansi 3.64 standard 1977 version:\
	:am:bs:mi:\
	:co#80:it#8:li#24:\
	:al=5*\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[;H\E[2J:\
	:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=5*\E[M:\
	:do=\E[B:ei=\E[4l:ho=\E[H:im=\E[4h:k1=\EOP:k2=\EOR:k4=\EOS:\
	:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\
	:nd=\E[C:nw=^M\ED:rc=\E8:sc=\E7:se=\E[m:sf=\ED:so=\E[7m:\
	:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:
Read like this: cursor up key (up) for example sends three characters: (escape), "[", and "A". The Enter key (cr) sends one character ^M (from the wiki page, that's ASCII 13). Backspace (kb) sends ^H (ASCII 8 ). As you can see there aren't many sequences at all. You don't need to implement nor to port termcap, just use its database to read the sequence codes.

Obviously you don't have to support all possible terminal sequences ever created, if you aim at VT220 sequences you're good, you won't have problems with any of the existing terminal emulators, ever.

In fact, if you implement ANSI terminal control characters (7 characters), CSI (14, without SGR and AUX), and from SGR only 0 (reset), 1 (bold), 30-37 (foreground color), 40-47 (background color), that's a total of only 39 sequences, that will give you a very very decent terminal implementation compatible out-of-the-box with PuTTY, minicom, xterm+screen or whatever terminal you use on the other side. Some UNIX sends ASCII 127 instead of ASCII 8 for ^H, and unless you're planning to support real terminals, you can forget about keys like "Do", "Help", "Find" or "Compose" too.

Check out https://vt100.net for all the docs and specs if you aim at full compatibility.

Cheers,
bzt
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: VBE higher resolution text modes support?

Post by rdos »

I think emulating text mode on top of a graphics mode is more useful. The only thing you need for that is a decent character generator. It's not as performance-effective, but you can construct any resolution you like (and that fits with the graphic resolution).
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: VBE higher resolution text modes support?

Post by nullplan »

rdos wrote:I think emulating text mode on top of a graphics mode is more useful. The only thing you need for that is a decent character generator. It's not as performance-effective, but you can construct any resolution you like (and that fits with the graphic resolution).
Agreed. You can get a linear framebuffer out of almost any graphics card in the world, but VGA text mode is more of a special beast. Bitmap fonts aren't that hard to render, even if you allow for multiple bit depths.
Carpe diem!
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: VBE higher resolution text modes support?

Post by xeyes »

bzt wrote:With overriding the VGA control registers, you can squeeze 90x60 out of a VGA video card (without using VESA).
Does this squeeze the characters even more than 80x50 or it has a higher resolution for real (aka makes Qemu/Bochs window grow bigger)?
bzt wrote: Not that difficult. Take a look at the wiki, there's a very-very simple example code on the VGA Fonts page (about 10 SLoC), a bit more optimized one on the PC Screen Font page (about 20 SLoC). Finally there's the dependency-free single header Scalable Screen Font library which provides a similar bitmap-only ssfn_putc() function (compiled size about 1K), and a more advanced ssfn_render() function which can scale, shape, kern glyphs and supports bitmap as well as scalable vector fonts too (total compiled size about 28K only).
rdos wrote: I think emulating text mode on top of a graphics mode is more useful. The only thing you need for that is a decent character generator. It's not as performance-effective, but you can construct any resolution you like (and that fits with the graphic resolution).
nullplan wrote: Agreed. You can get a linear framebuffer out of almost any graphics card in the world, but VGA text mode is more of a special beast. Bitmap fonts aren't that hard to render, even if you allow for multiple bit depths.
Not too worried about code size as this is intended for a normal computer, but these don't seem trivial either for someone never dealt with graphics before. I assume linear frame buffer means the CPU writes pixels directly to a row major 2D array?

Also did some quick calculation: 1080p screen is 2M pixels, redrawing them at 60Hz means each pixel gets about 40 cycles on a 5Ghz CPU. That is assuming the I/O is not slowing the CPU down at all. Maybe not every pixel need to be redrawn at each frame. But at the end of the day it seems that a good algorithm is needed to get reasonable performance without actually tying up a 5Ghz CPU just to get some text out.

Maybe I'll stick with text mode for a long time until GUI is needed.
bzt wrote: Yes, they do send complex codes, but don't be frightened, here's a pretty comprehensive list of ANSI escape codes. For PuTTY, you can configure which sequences to send, and for Linux, it uses the termcap library, which has a human-readable "database" for the codes (under /etc/termcap), like

Code: Select all

ansi77|ansi 3.64 standard 1977 version:\
	:am:bs:mi:\
	:co#80:it#8:li#24:\
	:al=5*\E[L:bl=^G:cd=\E[J:ce=\E[K:cl=\E[;H\E[2J:\
	:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:dc=\E[P:dl=5*\E[M:\
	:do=\E[B:ei=\E[4l:ho=\E[H:im=\E[4h:k1=\EOP:k2=\EOR:k4=\EOS:\
	:kb=^H:kd=\E[B:kh=\E[H:kl=\E[D:kr=\E[C:ku=\E[A:le=^H:\
	:nd=\E[C:nw=^M\ED:rc=\E8:sc=\E7:se=\E[m:sf=\ED:so=\E[7m:\
	:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:
Read like this: cursor up key (up) for example sends three characters: (escape), "[", and "A". The Enter key (cr) sends one character ^M (from the wiki page, that's ASCII 13). Backspace (kb) sends ^H (ASCII 8 ). As you can see there aren't many sequences at all. You don't need to implement nor to port termcap, just use its database to read the sequence codes.

Obviously you don't have to support all possible terminal sequences ever created, if you aim at VT220 sequences you're good, you won't have problems with any of the existing terminal emulators, ever.

In fact, if you implement ANSI terminal control characters (7 characters), CSI (14, without SGR and AUX), and from SGR only 0 (reset), 1 (bold), 30-37 (foreground color), 40-47 (background color), that's a total of only 39 sequences, that will give you a very very decent terminal implementation compatible out-of-the-box with PuTTY, minicom, xterm+screen or whatever terminal you use on the other side. Some UNIX sends ASCII 127 instead of ASCII 8 for ^H, and unless you're planning to support real terminals, you can forget about keys like "Do", "Help", "Find" or "Compose" too.

Check out https://vt100.net for all the docs and specs if you aim at full compatibility.

Cheers,
bzt
I actually support 1 escape code (ESC[2J) to let a program clear the screen :D

But isn't this case the other way around? My code would be sending these output escape codes like move cursor to X and Y via serial to Putty running on the host in order to draw. They'll send me a different set of input codes for things such as "the user has pressed/released enter key" just like a PS/2 keyboard's scan codes?

If that is the case I can easily forgo the eye candies such as colors, as long as I can interpret alphanumerical key inputs and a few control keys like ctrl, etc.
Octocontrabass
Member
Member
Posts: 5568
Joined: Mon Mar 25, 2013 7:01 pm

Re: VBE higher resolution text modes support?

Post by Octocontrabass »

xeyes wrote:Does this squeeze the characters even more than 80x50 or it has a higher resolution for real (aka makes Qemu/Bochs window grow bigger)?
It really does have a higher resolution.
xeyes wrote:Not too worried about code size as this is intended for a normal computer, but these don't seem trivial either for someone never dealt with graphics before. I assume linear frame buffer means the CPU writes pixels directly to a row major 2D array?
That is correct. I think it's pretty easy, but maybe that's just me...
xeyes wrote:But at the end of the day it seems that a good algorithm is needed to get reasonable performance without actually tying up a 5Ghz CPU just to get some text out.
Redrawing the entire screen will be slow, but how often do you need to do that? Only pixels that change need to be redrawn.
xeyes wrote:Maybe I'll stick with text mode for a long time until GUI is needed.
That's not an option if you want to try your OS on a PC without text mode.
xeyes wrote:But isn't this case the other way around? My code would be sending these output escape codes like move cursor to X and Y via serial to Putty running on the host in order to draw. They'll send me a different set of input codes for things such as "the user has pressed/released enter key" just like a PS/2 keyboard's scan codes?
No, input and output usually use the same set of codes. For example, an ANSI terminal will send the "move cursor" escape codes for the arrow keys.
xeyes wrote:If that is the case I can easily forgo the eye candies such as colors, as long as I can interpret alphanumerical key inputs and a few control keys like ctrl, etc.
Modifier keys usually only modify the input codes rather than having input codes of their own, and the modified codes may not be unique. For example, an ANSI terminal will send the same code for the enter key and ctrl+M.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VBE higher resolution text modes support?

Post by bzt »

xeyes wrote:Does this squeeze the characters even more than 80x50 or it has a higher resolution for real (aka makes Qemu/Bochs window grow bigger)?
It will use 8x8 fonts, so with 90x60 you'll get the resolution of 720x480.
xeyes wrote:Not too worried about code size as this is intended for a normal computer, but these don't seem trivial either for someone never dealt with graphics before.
Look, Scalable Screen Font is a fully featured font renderer that deals with both geometrically compressed and deflated fonts and supports scalable vector fonts too. Of course it's not trivial. However if you have an uncompressed 8x16 bitmap font only (same as in the VGA ROM), then your code can be as trivial as:

Code: Select all

void drawchar(unsigned char c, int x, int y, int fgcolor, int bgcolor)
{
	int cx, cy;
	for(cy = 0; cy < 16; cy++){
		for(cx = 0; cx < 8; cx++){
			putpixel( font[c * 16 + cy] & (1 << cx) ? fgcolor : bgcolor, x + cx, y + cy - 12);
		}
	}
}
Basically you iterate through the bitmap, and plot a pixel with either foreground or background color depending if the bit in the font is set or not font[c * 16 + cy] & (1 << cx). (This isn't an optimized code, it's a trivial one. Here we take advantage of the fact that the font is 8 pixels wide, so one row is stored in a byte, and the font is 16 pixels tall, so each and every glyph is stored in 16 bytes. That's c * 16. Then we add the current row to that c * 16 + cy, finally we check if the cxth bit is set in that row.)
xeyes wrote:I assume linear frame buffer means the CPU writes pixels directly to a row major 2D array?
Well, there's no such thing as row major in memory. That's just a notation on paper (this is a common confusion for DirectX and OpenGL developers too, their documentation uses different notation, but actually both using the same byte order in memory for a matrix.)

And not 2D, just a 1D array with gaps. So first come the first row's pixels, there might be a gap, and the second row's pixels. That's why it is important to get both screen width and pitch: the first tells how many pixels are on screen, and the second how many pixels are stored in memory. The two are often the same, but not always. For example, 800 x 600 true color. On screen you have 800 pixels, that's 3200 bytes, but the second row might start not on the 3200th byte but at the 4096th byte.
xeyes wrote:Maybe not every pixel need to be redrawn at each frame. But at the end of the day it seems that a good algorithm is needed to get reasonable performance without actually tying up a 5Ghz CPU just to get some text out.
Exactly. One change pixels that needs to be changed. And never read the framebuffer, that's slow, only write it.
xeyes wrote:Maybe I'll stick with text mode for a long time until GUI is needed.
This isn't really a choice, as @Octocontrabass pointed out. With modern machines you only have pixel mode. Text mode is already obsolete.
xeyes wrote:But isn't this case the other way around?
No, you have to make sure you use only known codes. That is:

Terminal to your app: keycodes, those listed in termcap, you should interpret all those.
Your app to terminal: only send ANSI CSI codes so you don't have to worry about the terminal's type.

Now some codes are the same for both: for example, if the user presses the [cursor up] key, then the terminal will send (escape)[A to your app. And if your app wishes to move the cursor on the terminal, it sends the same (escape)[A to the terminal. Likewise, if the user presses the [Home] key, then the terminal sends (escape)[H, and if you want to move the cursor to the top left corner of the screen you send the same (escape)[H sequence to the terminal.
xeyes wrote:My code would be sending these output escape codes like move cursor to X and Y via serial to Putty running on the host in order to draw. They'll send me a different set of input codes for things such as "the user has pressed/released enter key" just like a PS/2 keyboard's scan codes?
Exactly. Except there are common codes for both sets and there are no key released codes, and not scan codes are sent rather ASCII codes. Special keys send control codes: ^H, ^M etc. (see the wiki) or multi character sequence, which always starts with ASCII 27. What sequences the terminal sends depends on its configuration (whether Backspace sends ASCII 8 or ASCII 127, and the Function keys' sequences, the rest is quite standard), and what sequences you send to the terminal depends on you detecting the terminal's capabilities (using only a limited set of ANSI escape sequences guaranteed to work on all terminals).
xeyes wrote:If that is the case I can easily forgo the eye candies such as colors, as long as I can interpret alphanumerical key inputs and a few control keys like ctrl, etc.
Key modifiers aren't send either. The terminal is responsible for handling those, and it sends a different sequence. For example, pressing [C] will send the character ASCII 99 ("c"). Pressing [Shift]+[C] will send ASCII 67 ("C"). Pressing [Ctrl]+[C] will send ASCII 3 (^C). But yes, your app doesn't interpret the colors, only sends those. So if you don't send RGB sequences, only 0, 1, 30-37, 40-47 codes, then you'll be limited to 16 colors, but you don't have to care about the terminal's type, all will interpret those color codes correctly.

My advice is: interpret all VT100 - VT220 key codes (you can forget about VT52), try to support all Fn combinations. And only emit VT100 sequences. This will guarantee the most compatibility without difficult terminal detection code.

Cheers,
bzt
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: VBE higher resolution text modes support?

Post by xeyes »

Octocontrabass wrote:
xeyes wrote:Does this squeeze the characters even more than 80x50 or it has a higher resolution for real (aka makes Qemu/Bochs window grow bigger)?
It really does have a higher resolution.
bzt wrote:
xeyes wrote:Does this squeeze the characters even more than 80x50 or it has a higher resolution for real (aka makes Qemu/Bochs window grow bigger)?
It will use 8x8 fonts, so with 90x60 you'll get the resolution of 720x480.
Thanks. It indeed looks better than 80x50, maybe the characters are slightly less square-ish?

Have some questions about that code:
1. is there a convention to load code like this at a certain code segment? otherwise if loaded linearly, its 100h origin could overwrite ivt?
2. is it important to "tell the BIOS what we've done"? The code works without that part in emulators but resulted in a black screen on real hardware (which didn't seem to work too well with 80x50 either, the chars are gabbled).
Octocontrabass wrote:
xeyes wrote:Not too worried about code size as this is intended for a normal computer, but these don't seem trivial either for someone never dealt with graphics before. I assume linear frame buffer means the CPU writes pixels directly to a row major 2D array?
That is correct. I think it's pretty easy, but maybe that's just me...
xeyes wrote:But at the end of the day it seems that a good algorithm is needed to get reasonable performance without actually tying up a 5Ghz CPU just to get some text out.
Redrawing the entire screen will be slow, but how often do you need to do that? Only pixels that change need to be redrawn.
bzt wrote:
xeyes wrote:Not too worried about code size as this is intended for a normal computer, but these don't seem trivial either for someone never dealt with graphics before.
Look, Scalable Screen Font is a fully featured font renderer that deals with both geometrically compressed and deflated fonts and supports scalable vector fonts too. Of course it's not trivial. However if you have an uncompressed 8x16 bitmap font only (same as in the VGA ROM), then your code can be as trivial as:

Code: Select all

void drawchar(unsigned char c, int x, int y, int fgcolor, int bgcolor)
{
	int cx, cy;
	for(cy = 0; cy < 16; cy++){
		for(cx = 0; cx < 8; cx++){
			putpixel( font[c * 16 + cy] & (1 << cx) ? fgcolor : bgcolor, x + cx, y + cy - 12);
		}
	}
}
Basically you iterate through the bitmap, and plot a pixel with either foreground or background color depending if the bit in the font is set or not font[c * 16 + cy] & (1 << cx). (This isn't an optimized code, it's a trivial one. Here we take advantage of the fact that the font is 8 pixels wide, so one row is stored in a byte, and the font is 16 pixels tall, so each and every glyph is stored in 16 bytes. That's c * 16. Then we add the current row to that c * 16 + cy, finally we check if the cxth bit is set in that row.)
xeyes wrote:I assume linear frame buffer means the CPU writes pixels directly to a row major 2D array?
Well, there's no such thing as row major in memory. That's just a notation on paper (this is a common confusion for DirectX and OpenGL developers too, their documentation uses different notation, but actually both using the same byte order in memory for a matrix.)

And not 2D, just a 1D array with gaps. So first come the first row's pixels, there might be a gap, and the second row's pixels. That's why it is important to get both screen width and pitch: the first tells how many pixels are on screen, and the second how many pixels are stored in memory. The two are often the same, but not always. For example, 800 x 600 true color. On screen you have 800 pixels, that's 3200 bytes, but the second row might start not on the 3200th byte but at the 4096th byte.
xeyes wrote:Maybe not every pixel need to be redrawn at each frame. But at the end of the day it seems that a good algorithm is needed to get reasonable performance without actually tying up a 5Ghz CPU just to get some text out.
Exactly. One change pixels that needs to be changed. And never read the framebuffer, that's slow, only write it.
Thanks for the details, I feel like doing graphics as well as the emulation of text in a more methodical fashion when I learn more about it. Unfortunately that also means waiting for bigger chunks of free time to do readings:(
Octocontrabass wrote:That's not an option if you want to try your OS on a PC without text mode.
bzt wrote:This isn't really a choice, as @Octocontrabass pointed out. With modern machines you only have pixel mode. Text mode is already obsolete.
I thought text mode is a common denominator of x86 PCs? What kind of machines don't have it?
Octocontrabass wrote:
xeyes wrote:But isn't this case the other way around? My code would be sending these output escape codes like move cursor to X and Y via serial to Putty running on the host in order to draw. They'll send me a different set of input codes for things such as "the user has pressed/released enter key" just like a PS/2 keyboard's scan codes?
No, input and output usually use the same set of codes. For example, an ANSI terminal will send the "move cursor" escape codes for the arrow keys.
xeyes wrote:If that is the case I can easily forgo the eye candies such as colors, as long as I can interpret alphanumerical key inputs and a few control keys like ctrl, etc.
Modifier keys usually only modify the input codes rather than having input codes of their own, and the modified codes may not be unique. For example, an ANSI terminal will send the same code for the enter key and ctrl+M.
bzt wrote:
xeyes wrote:But isn't this case the other way around?
No, you have to make sure you use only known codes. That is:

Terminal to your app: keycodes, those listed in termcap, you should interpret all those.
Your app to terminal: only send ANSI CSI codes so you don't have to worry about the terminal's type.

Now some codes are the same for both: for example, if the user presses the [cursor up] key, then the terminal will send (escape)[A to your app. And if your app wishes to move the cursor on the terminal, it sends the same (escape)[A to the terminal. Likewise, if the user presses the [Home] key, then the terminal sends (escape)[H, and if you want to move the cursor to the top left corner of the screen you send the same (escape)[H sequence to the terminal.
xeyes wrote:My code would be sending these output escape codes like move cursor to X and Y via serial to Putty running on the host in order to draw. They'll send me a different set of input codes for things such as "the user has pressed/released enter key" just like a PS/2 keyboard's scan codes?
Exactly. Except there are common codes for both sets and there are no key released codes, and not scan codes are sent rather ASCII codes. Special keys send control codes: ^H, ^M etc. (see the wiki) or multi character sequence, which always starts with ASCII 27. What sequences the terminal sends depends on its configuration (whether Backspace sends ASCII 8 or ASCII 127, and the Function keys' sequences, the rest is quite standard), and what sequences you send to the terminal depends on you detecting the terminal's capabilities (using only a limited set of ANSI escape sequences guaranteed to work on all terminals).
xeyes wrote:If that is the case I can easily forgo the eye candies such as colors, as long as I can interpret alphanumerical key inputs and a few control keys like ctrl, etc.
Key modifiers aren't send either. The terminal is responsible for handling those, and it sends a different sequence. For example, pressing [C] will send the character ASCII 99 ("c"). Pressing [Shift]+[C] will send ASCII 67 ("C"). Pressing [Ctrl]+[C] will send ASCII 3 (^C). But yes, your app doesn't interpret the colors, only sends those. So if you don't send RGB sequences, only 0, 1, 30-37, 40-47 codes, then you'll be limited to 16 colors, but you don't have to care about the terminal's type, all will interpret those color codes correctly.

My advice is: interpret all VT100 - VT220 key codes (you can forget about VT52), try to support all Fn combinations. And only emit VT100 sequences. This will guarantee the most compatibility without difficult terminal detection code.
Got it, that's a clever design to share codes in both directions but also seem to be so natural once I learned about that fact.

This looks like the a quick route to get a more 'usable' console/terminal, I added the serial read and interpretation of a few codes (enter, bksp) so its functionality still lags the text mode console. But has a much more pleasant view than the 'high resolution VGA' mode even at this stage. Plus 'free' buffering and scrolling provided by Qemu :lol:

Now just need to implement the remaining 95% of the escape codes and figure out how to not duplicate my messy input state machine between keyboard and serial.
Attachments
serial.jpg
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VBE higher resolution text modes support?

Post by bzt »

xeyes wrote:1. is there a convention to load code like this at a certain code segment? otherwise if loaded linearly, its 100h origin could overwrite ivt?
No, there isn't. That 100h offset is because that code was written for DOS, where the code segment starts with a Program Segment Prefix which is 256 bytes. But the segment isn't 0, so offset 100h isn't pointing in the middle of the IVT.
xeyes wrote:2. is it important to "tell the BIOS what we've done"? The code works without that part in emulators but resulted in a black screen on real hardware (which didn't seem to work too well with 80x50 either, the chars are gabbled).
If you don't use the BIOS on screen, then no, it isn't important. If it doesn't work on real hardware, that's more likely because your hardware doesn't have a real VGA card any more, just an emulated one.
xeyes wrote:I thought text mode is a common denominator of x86 PCs? What kind of machines don't have it?
Let's just say that ancient x86 PCs are the only one that have it... :-) Neither modern UEFI PCs nor anything else (ARM boards, Amiga, whatever).
xeyes wrote:Now just need to implement the remaining 95% of the escape codes and figure out how to not duplicate my messy input state machine between keyboard and serial.
I've created the Terminals page on our wiki, maybe it's going to be helpful.

Cheers,
bzt
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: VBE higher resolution text modes support?

Post by rdos »

bzt wrote:Let's just say that ancient x86 PCs are the only one that have it... :-) Neither modern UEFI PCs nor anything else (ARM boards, Amiga, whatever).
I wouldn't say ancient. Every x86 PC that is able to boot with BIOS also has text mode. It's a bit of a requirement. If you boot with UEFI, you typically won't have it, but the hardware still supports it if it also boots with BIOS. And most modern PCs actually can be configured for BIOS boot.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: VBE higher resolution text modes support?

Post by bzt »

rdos wrote:I wouldn't say ancient. Every x86 PC that is able to boot with BIOS also has text mode.
Only an emulated one. Real text mode has long gone with the VGA cards. That's the problem of the OP, that their video card does not provide full VGA emulation, only the basics, that's why the VGA register tweak doesn't work. Obviously if the hardware emulation is limited, then so must be the BIOS emulation too.
rdos wrote:It's a bit of a requirement. If you boot with UEFI, you typically won't have it, but the hardware still supports it if it also boots with BIOS. And most modern PCs actually can be configured for BIOS boot.
You're mistaken. If a machine has UEFI, then it doesn't have BIOS, those are mutually exclusive firmware. UEFI has something called CSM and legacy boot, which emulates some (but not all, see the source here) parts of the BIOS, but that's not BIOS, just a rudimentary emulation for the most important services to get an OS booted. However last year CSM got obsoleted too, meaning PCs produced this year don't have neither BIOS nor CSM any more, only UEFI.
By 2020, Intel will be only supporting UEFI Class 3, which means no legacy support of CSM compatibility.
(Some manufacturers still might ship UEFI with CSM option, but that's not mainstream any more as of 2021)

Cheers,
bzt
rdos
Member
Member
Posts: 3297
Joined: Wed Oct 01, 2008 1:55 pm

Re: VBE higher resolution text modes support?

Post by rdos »

bzt wrote:
rdos wrote:I wouldn't say ancient. Every x86 PC that is able to boot with BIOS also has text mode.
Only an emulated one. Real text mode has long gone with the VGA cards. That's the problem of the OP, that their video card does not provide full VGA emulation, only the basics, that's why the VGA register tweak doesn't work. Obviously if the hardware emulation is limited, then so must be the BIOS emulation too.
Well, I only meant the 80x25 setup. There is no reason to emulate long outdated tweaked text modes, or the ancient bit-plane modes of VGA.
bzt wrote: You're mistaken. If a machine has UEFI, then it doesn't have BIOS, those are mutually exclusive firmware. UEFI has something called CSM and legacy boot, which emulates some (but not all, see the source here) parts of the BIOS, but that's not BIOS, just a rudimentary emulation for the most important services to get an OS booted. However last year CSM got obsoleted too, meaning PCs produced this year don't have neither BIOS nor CSM any more, only UEFI.
By 2020, Intel will be only supporting UEFI Class 3, which means no legacy support of CSM compatibility.
(Some manufacturers still might ship UEFI with CSM option, but that's not mainstream any more as of 2021)

Cheers,
bzt
Interesting. It was only a matter of time so not unexpected. Not a problem for me since I can boot with both 32-bit and 64-bit UEFI. As long as they keep protected mode I will be fine.

OTOH, Intels linear framebuffer (LFB) support is horrible, which is much worse than the missing legacy boot and CSM. I will never buy another Intel based machine for that reason. AMDs LFB implementation is decent though.
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: VBE higher resolution text modes support?

Post by xeyes »

bzt wrote:
xeyes wrote:1. is there a convention to load code like this at a certain code segment? otherwise if loaded linearly, its 100h origin could overwrite ivt?
No, there isn't. That 100h offset is because that code was written for DOS, where the code segment starts with a Program Segment Prefix which is 256 bytes. But the segment isn't 0, so offset 100h isn't pointing in the middle of the IVT.
xeyes wrote:2. is it important to "tell the BIOS what we've done"? The code works without that part in emulators but resulted in a black screen on real hardware (which didn't seem to work too well with 80x50 either, the chars are gabbled).
If you don't use the BIOS on screen, then no, it isn't important. If it doesn't work on real hardware, that's more likely because your hardware doesn't have a real VGA card any more, just an emulated one.
xeyes wrote:I thought text mode is a common denominator of x86 PCs? What kind of machines don't have it?
Let's just say that ancient x86 PCs are the only one that have it... :-) Neither modern UEFI PCs nor anything else (ARM boards, Amiga, whatever).
xeyes wrote:Now just need to implement the remaining 95% of the escape codes and figure out how to not duplicate my messy input state machine between keyboard and serial.
I've created the Terminals page on our wiki, maybe it's going to be helpful.

Cheers,
bzt
Wow that's a nice wiki page done in such short period of time, thanks!

What does "don't use the BIOS on screen" mean though?

Fortunately most of my UEFI machines aren't class 3 :lol:
Post Reply