Writing to the screen without BIOS

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
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Writing to the screen without BIOS

Post by PavelChekov »

Babystep4 and 8 show how to write to the screen without BIOS interrupts in 16- and 32-bit real and protected modes, respectively. I am trying to write a 64-bit OS, and I want to avoid using BIOS interrupts as much as I can. Is there a way to write to the screen without BIOS in a 64-bit OS? Is there such thing as 64-bit protected mode?

Thanks
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Writing to the screen without BIOS

Post by Octocontrabass »

PavelCheckov wrote:Is there a way to write to the screen without BIOS in a 64-bit OS?
Writing to the VGA text mode screen works the same regardless of CPU mode. I suggest you read more about VGA text mode if you don't understand the babystep code.

UEFI doesn't have VGA text mode, so if you want to support UEFI in the future you'll have to write new code to support a linear frame buffer. (You can also have a linear frame buffer with BIOS.)
PavelCheckov wrote:Is there such thing as 64-bit protected mode?
It's called "long mode".
User avatar
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Re: Writing to the screen without BIOS

Post by PavelChekov »

Octocontrabass wrote:Writing to the VGA text mode screen works the same regardless of CPU mode. I suggest you read more about VGA text mode if you don't understand the babystep code.
The only reason I ask is because it says that the code is for 32-bit protected mode. I was also hoping to use FHD as the default, which doesn't have text mode, or to my knoweledge, any tutorial.
Octocontrabass wrote:UEFI doesn't have VGA text mode, so if you want to support UEFI in the future you'll have to write new code to support a linear frame buffer. (You can also have a linear frame buffer with BIOS.)
I was hoping to write my OS independent of a specific BIOS (e.g. UEFI).

Octocontrabass wrote:It's called "long mode".
How do I enter long mode?
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Writing to the screen without BIOS

Post by Octocontrabass »

PavelCheckov wrote:I was also hoping to use FHD as the default, which doesn't have text mode, or to my knoweledge, any tutorial.
So, you want a linear frame buffer. There's quite a bit of information on how to use one of those. Please ignore the page title - it was probably written before long mode existed.
PavelCheckov wrote:I was hoping to write my OS independent of a specific BIOS (e.g. UEFI).
You want a linear frame buffer.
PavelCheckov wrote:How do I enter long mode?
Let the bootloader do it for you.

...But, you can find an overview on the wiki in case your bootloader doesn't already do it. If you search, you'll probably find example code too.
User avatar
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Re: Writing to the screen without BIOS

Post by PavelChekov »

All the examples are for VGA, and I am still unclear how to write text to an XGA screen (via linear frame buffer).
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Writing to the screen without BIOS

Post by Octocontrabass »

Which examples are you looking at? I provided a link to the wiki page that explains how to draw text to a linear frame buffer. It works the same for all linear frame buffers.
User avatar
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Re: Writing to the screen without BIOS

Post by PavelChekov »

I am looking at the link provided, but it appears to be for VGA and BIOS, however I am programming with XGA and UEFI.
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
User avatar
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Re: Writing to the screen without BIOS

Post by PavelChekov »

How would I write a printf function with this?
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Writing to the screen without BIOS

Post by iansjack »

You write a function to draw a single character to the screen. From then on, writing printf is exactly the same as if you were using BIOS calls to write characters to the screen.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Writing to the screen without BIOS

Post by bzt »

PavelCheckov wrote:How would I write a printf function with this?
To display a character, take a look at the example on PC Screen Font wiki page. You just repeat that code for every character and adjust the cursor position. A very very minimalistic string display example would be:

Code: Select all

// PSF2 header
typedef struct {
    uint32_t magic;
    uint32_t version;
    uint32_t headersize;
    uint32_t flags;
    uint32_t numglyph;
    uint32_t bytesperglyph;
    uint32_t height;
    uint32_t width;
    uint8_t glyphs;
} __attribute__((packed)) psf2_t;
extern volatile unsigned char _binary_font_psf_start;

void puts(char *s)
{
    psf2_t *font = (psf2_t*)&_binary_font_psf_start;
    int x,y,kx=0,line,mask,offs;
    int bpl=(font->width+7)/8;
    while(*s) {
        unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->headersize +
            (*s>0&&*s<font->numglyph?*s:0)*font->bytesperglyph;
        offs = (kx * (font->width+1) * 4);
        for(y=0;y<font->height;y++) {
            line=offs; mask=1<<(font->width-1);
            for(x=0;x<font->width;x++) {
                *((uint32_t*)(framebuffer_address+line))=((int)*glyph) & (mask)?0xFFFFFF:0;
                mask>>=1; line+=4;
            }
            *((uint32_t*)((uint64_t)&fb+line))=0; glyph+=bpl; offs+=framebuffer_scanline;
        }
        s++; kx++;
    }
}
As for the arguments, you should implement sprintf, construct the output buffer and pass that to this "puts" function.

You probably want more than this simple example, like handling newline characters, interpret UTF-8, proportional fonts etc. For these, you can find a ready-to-use, dependency free library, Scalable Screen Font. It has a minimalistic routine, comparable to the PC Screen Font example above, see ssfn_putc.

Cheers,
bzt
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Writing to the screen without BIOS

Post by nexos »

PavelCheckov wrote:How would I write a printf function with this?
Basically, you write a routine that renders a font to screen (PC Screen Font is fine, just don't copy n' paste blindly, understand the code first before copying). After that, read up on the ISO C standard or POSIX specification about printf and how it works, and then write it.

Or, in the words of Bill Joy:
It's very simple — you read the protocol and write the code
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Re: Writing to the screen without BIOS

Post by PavelChekov »

Will this code work, modified for XGA, with GOP, even though it was written for VESA? (From the article on drawing in the linear frame buffer)

Code: Select all

/* example for 320x200 VGA */
void putpixel(int pos_x, int pos_y, unsigned char VGA_COLOR)
{
    unsigned char* location = (unsigned char*)0xA0000 + 320 * pos_y + pos_x;
    *location = VGA_COLOR;
}
(https://wiki.osdev.org/Drawing_In_Protected_Mode)
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Writing to the screen without BIOS

Post by Octocontrabass »

That code was written for VGA, not VBE. Code written for VGA will not work with GOP. (GOP does not support indexed color modes.)
Actually, I read your post wrong. If you modify it, then yes, you can make it work. The article already has an example of one way you could modify it:

Code: Select all

static void putpixel(unsigned char* screen, int x,int y, int color) {
    unsigned where = x*pixelwidth + y*pitch;
    screen[where] = color & 255;              // BLUE
    screen[where + 1] = (color >> 8) & 255;   // GREEN
    screen[where + 2] = (color >> 16) & 255;  // RED
}
User avatar
PavelChekov
Member
Member
Posts: 113
Joined: Mon Sep 21, 2020 9:51 am
Location: Aboard the Enterprise

Re: Writing to the screen without BIOS

Post by PavelChekov »

So, that code would work in GOP even thought it was meant for VESA? And truecolor?
USS Enterprise NCC-1701,
The Final Frontier,
Space,
The Universe

Live Long And Prosper

Slava Ukraini!
Слава Україні!
Post Reply