-
-
Notifications
You must be signed in to change notification settings - Fork 625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for VGA console output in bare metal mode #588
Conversation
libc/vga/writev-vga.c
Outdated
/* TODO: ensure screen in a known mode (text or graphics), at rlinit time */ | ||
/* TODO: use our own font, rather than rely on BIOS's CP437 font */ | ||
/* TODO: handle UTF-8 multi-bytes */ | ||
/* TODO: handle VT102 escape sequences */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is https://github.com/jart/cosmopolitan/blob/master/tool/build/lib/pty.c something that might be useful to you? It's how Blinkenlights displays a terminal inside a terminal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is https://github.com/jart/cosmopolitan/blob/master/tool/build/lib/pty.c something that might be useful to you?
Thank you — yes, this looks like it might be useful to me. Let me take a further look at the pty.c
code and see how I can use it.
initial cursor position as left by BIOS
By the way those checkboxes shouldn't need to be blockers. It'd be great to get an incremental improvement merged and then keep sending more changes. Works of progress are great so long as tests pass. |
Thanks @jart. I am currently working on implementing some basic VT102 support based on a pared-down version of Thank you! |
The code is based on a pared-down version of the pty code in tool/build/lib/pty.c. It currently adds about 12 KiB to the size of the final executable (compared to the earlier (simplistic) teletype implementation). Some terminal features, such as kTtyBell & kTtyNocursor, are not yet implemented.
Hello @jart, The VT102 and UTF-8 support (based on
and I see some remaining issues:
Other than the above, the PR should be ready to merge now, if that is fine with you. Thank you! |
That's really small and it's not a problem at all, since we're using
Please do not implement the terminal bell. It's very distracting.
You can't link unbing()? You should be able to, since |
The prospect of writing 32-bit/64-bit C code that also runs and displays on PC VGA hardware is exciting. I can see some very nice usefulness in writing sophisticated programs using Cosmopolitan that can run and display without an operating system, particularly for TUI programs. I thought to ask a few questions and comments on this work, both to make sure I fully understand how it works, as well to make a suggestion about a future enhancement for maximum TUI usability. I don't quite understand why all of the wcs, bing/unbing and other extensive translation support needs to be carried along with this code, intended for operation only on IBM PC systems with VGA hardware. The hardware can only display cp437 (in text modes), which it does continuously for all (8-bit) characters and attributes within its current displayed text memory page. So why not just translate from UTF-8 to cp437 once, immediately upon receiving or converting the Unicode input, and then keeping the data in cp437 without the complex translation routines? What is the purpose of carrying the wcs[] array, when the character data will never be inspected or available to the host program? It seems there is quite a bit of extra code being kept (from pty.c), which won't be used as a result of VGA hardware. Of course, if the VGA is in graphics mode and is drawing each glyph using software, that would be quite different. Is that the reason? I suppose all this doesn't really matter, since 12K is quite small compared to the bloat of modern day programs, but was thinking that perhaps text-only versus graphics mode glyphs might want to be considered to be implemented/yoinked in separately, to keep the ability to create very tiny bare metal programs. Just some thoughts :) The VT100/102/220 terminals have a special characteristic, implemented by very few other terminals, which comes in very handy for those writing full-screen TUI applications: the ability to write the character in the last line and last column, without the screen scrolling. This characteristic is described by "XN hack/soft-wrap", Thank you! |
Hello @jart,
Yes, it is so.
OK.
Thanks! Using Thank you! |
Hello @ghaerr,
Well, the The Linux kernel mailing list thread regarding Linux's
I believe @jart's Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Great work!
Hello @jart, Thank you again! For the terminal features, would you prefer to support blinking characters, or to support bright (high intensity) background colours? I see that the VGA BIOSes allow one to change the meaning of the text buffer's high attribute bits to yield bright backgrounds. (It seems that Linux currently has decided to support blinking and err on the dark side for backgrounds.) Thank you! |
What the terminal calls "bright" is in practice usually just a different shade of the 16 ANSI colors, so you can get 32 colors in total. I use this theme for that:
There's also Blinking is annoying. If it were 100% free to support, I'd say do it. But if we need to add things like timers and other bloat, then it's probably not worth it. The features I care about are what's implemented in pty.c. Namely things like XTERM256, 24-bit color, etc. I also care deeply about being able to use UNICODE characters if possible. At the very minimum CP-437. Every file in this codebase uses UNICODE characters that are part of CP437. There's also some files in the codebase which use astral plane mathematical characters in comments. I love characters. Definitely err on the dark side for background. Not sure I understand Torvalds' hack there. But looks interesting. |
Hello @jart,
Blinking is almost 100% free in VGA text mode. The VGA hardware directly supports it. But if blinking is used, then we cannot have bright background colours — for the entire screen. More precisely, there is a hardware setting (which can be set by BIOS
or
(QEMU does not emulate VGA's text mode blinking; but VirtualBox does.) Thank you! |
In that case it's a no-brainer. Blinking would be bad. |
For what it's worth, because the EGA/VGA blink bit is system-wide and the previous state not necessarily tracked by early (non-VGA) BIOSes, all of the color code in the TUI library I'm developing for Cosmopolitan never attempts to set or clear the blink/background intensity bit. That is, applications only have 16 fg and 8 bg colors available, and bright background versus blink is a non-issue. (The current TUI color and cp437 handling for D-Flat is in tty-cp437.c and tty.c, and is compatible with this PR. I plan on creating a Cosmopolitan bare metal version of it to exercise and show off the new VGA console output capabilities, as well as contribute the TUI library (broken into smaller modules) into Cosmopolitan at tools/tui). Along the lines of implementing a modern (bare metal) console, if the console were to implement the private mode sequence(s) ESC [ ? 1000 h, (possibly along with 1002, 1006 and 1015 mouse status variations), then TUI bare metal applications would have mouse input capability from Cosmopolitan without having to worry about a mouse driver. Since most xterm256 and other host terminal emulators already do this, that would provide a nice compatibility layer between different Cosmopolitan modes. Thank you! |
Hello @tkchia, I finally ported D-Flat to Cosmopolitan, described and tracked in shmup/awesome-cosmopolitan#2, which is a TUI library that takes advantage of the CP437 character set as well as lots of 16-color foreground and 8-color background color use. It uses ANSI ESC sequences throughout, and I thought it might be useful for testing or showing off your new VGA bare metal support. The library uses May I ask whether you're using an emulator for VGA bare metal testing, and what the command line is, so I can help test D-Flat on VGA? Thank you! |
Hello @ghaerr, I am mostly using QEMU, with a simple command line, like so:
or
You can also get debugging dumps from QEMU using the Thank you! |
* | ||
* @see lkml.kernel.org/lkml/204888.1529277815@turing-police.cc.vt.edu/T/ | ||
*/ | ||
#undef VGA_USE_WCS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this correct, its check for VGA_USE_WCS
later down the header, and it will turn it off for writev-vga.c
& tty.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @paulwratt,
Yes. This is intentional.
/*
* VGA_TTY_HEIGHT, VGA_TTY_WIDTH, & VGA_USE_WCS are configuration knobs
* which can potentially be used to tweak the features to be compiled into
* our VGA teletypewriter support.
*/
Thank you!
Is there any chance we could get a VGA demo added to the examples/ folder that has a comment at the top:
If you want to see our Cosmopolitan CGA demo:
|
Hello @ghaerr,
OK. I am in the process of getting this implemented. It looks like, besides implementing Thank you! |
Hello @tkchia,
Yes, and I hadn't thought of that
[EDIT: I hadn't realized that Cosmopolitan already handles calling target routines based on the file descriptor. I need to study that portion of libc in more detail.] Thank you! |
Hello @ghaerr, 🙂 Then again, it seems the common use case for "reading" from a display driver, is to simply obtain the raw status response strings. So perhaps we can do just that, and ignore the Thank you! |
Hello @tkchia,
Well, yes, but also the "console device" should return anything typed from the keyboard too, since that and the status response strings are part of the same stream, right?. I admit to not being familiar with this portion of Cosmopolitan yet - does a console read result an INT 16h (read keyboard) or other function for bare metal at this time? The
Looks good. I notice that currently the driver is always non-blocking, and it seems it will return 0 on no data available. That shouldn't be a problem, but I wanted to mention the overall structure of how most Cosmopolitan TUI programs and the proposed TUI library deal with text input in general: In some simpler cases, the TUI program hangs on the Thank you! |
Hello @ghaerr,
Currently only input via serial port is implemented. There is no code yet for reading from a keyboard, whether via the PS/2 interface or via USB. Unfortunately, IRQs — needed to handle asynchronous events and timeouts — are also not yet implemented. (But they really should be!) Thank you! |
Termios is something we certainly need. How it's configured takes some getting used to. The stuff that matters the most is documented in the "commentary" column of libc/sysv/consts.sh cosmopolitan/libc/sysv/consts.sh Lines 1472 to 1477 in 446a1f7
For example, Another important one is I've updated the I'm typing via the serial port and it's showing up on the display. Some of the codes that come later are for example the arrow keys. |
Hello @jart,
I am glad it works. 🙂
Is this something you would also like to get implemented in the existing serial input code ( Thank you! |
Very much so. |
I have added (as of https://github.com/tkchia/cosmopolitan/commit/c42c607c80c2920b585ee1a65a9c66ec68acd609) some very rough and preliminary support for console output to the VGA screen — in addition to the serial port — when in bare metal mode.
I hope to improve on it further, e.g.:
rlinit
time (rather than simply assuming that the screen is in the classical 80 × 25 × 16 text mode, with a text buffer at address0xb8000
); (✓ https://github.com/tkchia/cosmopolitan/pull/588/commits/aeacc4239dc14b9adfaa7be80bde9a6f4711f7f8)switch to using a font embedded in the program, rather than rely on the BIOS's CP437 font;maybe handle the BEL ('\a'
) character code.