Basic printing text problem

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
kkmk
Posts: 4
Joined: Tue Mar 17, 2020 4:22 am

Basic printing text problem

Post by kkmk »

I'm new to OS development and I encountered pretty silly problem regarding printing text on screen while using colors. Here is my function:

Code: Select all

void _sysprintf(char* str, uint8_t bgcolor, uint8_t forecolor) {
    static uint16_t* VideoMemory = (uint16_t*)0xb8000;
    static uint8_t x = 0, y = 0;
    uint8_t text_color = ((bgcolor) << 4) | (forecolor & 0x0F);

    for(int i = 0; str[i] != '\0'; ++i)
    {
        switch(str[i])
        {
            case '\n':
                y++;
                x = 0;
                break;

            case '\b':
                if (x <= 0)
                {
                    x = 0;
                }
                else {
                    x -= 1;
                }
                VideoMemory[80*y+x] = (VideoMemory[80*y+x] & 0xFF00) | ' ';
                break;

            default:
                VideoMemory[80*y+x] = (VideoMemory[80*y+x] & (text_color << 8)) | str[i];
                x++;
                break;
        }

        if(x >= 80) {
            y++;
            x = 0;
        }

        if (y >= 25) {
            for(y = 0; y < 25; y++)
            for(x = 0; x < 80; x++)
            VideoMemory[80*y+x] = (VideoMemory[80*y+x] & 0xFF00) | ' ';

            x = 0;
            y = 0;
        }
    }
    cursor_update(x, y);
}
And here is the code in main function printing out the colored text (ignore the difference between _sysprintf and printf, printf is referencing the _sysprintf without color values):

Code: Select all

    _sysprintf("A", 0x00, 0x00);
    _sysprintf("B", 0x00, 0x01);
    _sysprintf("C", 0x00, 0x02);
    _sysprintf("D", 0x00, 0x03);
    _sysprintf("E", 0x00, 0x04);
    _sysprintf("F", 0x00, 0x05);
    _sysprintf("G", 0x00, 0x06);
    _sysprintf("H", 0x00, 0x07);
    _sysprintf("I", 0x00, 0x08);
    _sysprintf("J", 0x00, 0x09);
    _sysprintf("K", 0x00, 0x10);
    _sysprintf("L", 0x00, 0x11);
    _sysprintf("M", 0x00, 0x12);
    _sysprintf("N", 0x00, 0x13);
    _sysprintf("O", 0x00, 0x14);
    _sysprintf("!", 0x00, 0x15);

    printf("\n");

    _sysprintf("!", 0x00, 0x00);
    _sysprintf("A", 0x01, 0x00);
    _sysprintf("B", 0x02, 0x00);
    _sysprintf("C", 0x03, 0x00);
    _sysprintf("D", 0x04, 0x00);
    _sysprintf("E", 0x05, 0x00);
    _sysprintf("F", 0x06, 0x00);
    _sysprintf("G", 0x07, 0x00);
    _sysprintf("H", 0x08, 0x00);
    _sysprintf("I", 0x09, 0x00);
    _sysprintf("J", 0x10, 0x00);
    _sysprintf("K", 0x11, 0x00);
    _sysprintf("L", 0x12, 0x00);
    _sysprintf("M", 0x13, 0x00);
    _sysprintf("N", 0x14, 0x00);
    _sysprintf("O", 0x15, 0x00);
The result is that not only the colors don't match the expected outcome but also if I clear the screen, the colors are not overwritten by default black background/white text spaces as I would expect. Also please ignore the white space in middle of screen, that's just mouse cursor.

Image

Image

I tried many different solutions, I was looking up for answers and nothing worked. I think this must be some kind of very silly mistake, am I shifting the bytes in wrong way?
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Basic printing text problem

Post by iansjack »

Code: Select all

for(int i = 0; str[i] != '\0'; ++i)
Why ++i, rather than i++?
Octocontrabass
Member
Member
Posts: 5578
Joined: Mon Mar 25, 2013 7:01 pm

Re: Basic printing text problem

Post by Octocontrabass »

kkmk wrote:I think this must be some kind of very silly mistake
I agree.

Let's focus on clearing the screen first: which line of code sets the foreground and background colors back to the default white on black? (You should have trouble finding it, because it's not there.)
kkmk
Posts: 4
Joined: Tue Mar 17, 2020 4:22 am

Re: Basic printing text problem

Post by kkmk »

iansjack wrote:

Code: Select all

for(int i = 0; str[i] != '\0'; ++i)
Why ++i, rather than i++?
I changed it, thank you.
Octocontrabass wrote:
kkmk wrote:I think this must be some kind of very silly mistake
I agree.

Let's focus on clearing the screen first: which line of code sets the foreground and background colors back to the default white on black? (You should have trouble finding it, because it's not there.)
Another way of how I tested it was that I created function which would basically fill the whole screen with white characters/black background every time the screen height would reach the limit. It hadn't got the desired effect and those letters which were previously colored were also colored with overwritten screen of 'clear' page. I must be doing it wrong and the way how it works isn't by overwriting values but I have to somehow clear the stored value for character and color on that specific place of screen first? I've seen other example using memsetw function to clear screen. I can also do some silly hack like this which is not working:

Code: Select all

uint8_t clear_color = ((0x00) << 4) | (0x0F & 0x0F);
...
if (y >= 25) {
            ...
            VideoMemory[80*y+x] = (VideoMemory[80*y+x] & (clear_color << 8)) | ' ';
            ...
I also noticed thanks to you that I was dumb and the color codes run from 0x00->0x09 and then to 0x0A->0x0F; and not 0x10, 0x11, etc. So now the result looks like this:
Image
Octocontrabass
Member
Member
Posts: 5578
Joined: Mon Mar 25, 2013 7:01 pm

Re: Basic printing text problem

Post by Octocontrabass »

In C, what does the & operator do?
kkmk
Posts: 4
Joined: Tue Mar 17, 2020 4:22 am

Re: Basic printing text problem

Post by kkmk »

Octocontrabass wrote:In C, what does the & operator do?
Oh okay, I see:

Code: Select all

uint8_t clear_color = (0x00 << 4) | 0x0F;
...
if (y >= 25) {
            for(y = 0; y < 25; y++)
                for(x = 0; x < 80; x++)
                    VideoMemory[80*y+x] = clear_color << 8 | ' ';
...
Now it works.
kkmk
Posts: 4
Joined: Tue Mar 17, 2020 4:22 am

Re: Basic printing text problem

Post by kkmk »

Octocontrabass wrote:In C, what does the & operator do?
Now even the light colors work, background colors work and all issues are fixed. Thank you very much for having patience with me, I appreciate it a lot.
Post Reply