Page 1 of 1

Qemu and terminal scroll problem

Posted: Sat Feb 03, 2018 4:03 am
by darvark
Hi,
I'm already starting with osdev, but I'm stuck on one of the easiest part. Going throught Bare Bones tutorial I succeed with booting simple kernel, and handling new lines. But I can't figure out how to sole problem of scrolling terminal. After dozens of tries my own soutions I've found this one here on the forum:

Code: Select all

 void terminal_scroll(void) {
    int attrib = 0x0F;
    uint16_t blank;
    uint16_t temp;

    /**
    * A blank is defined as a space... we need to give it
    * backcolor too
    */
    blank = 0x20 | (attrib << 8);

    /**
    * Move the current text chunk that makes up the screen
    * back in the buffer by a line
    */
    temp = terminal_row - 25 + 1;
    memcpy(terminal_buffer, terminal_buffer + temp * 80, (25 - temp) * 80 * 2);

    /**
    * Finally, we set the chunk of memory that occupies
    * the last line of text to our 'blank' character
    */

    memset(terminal_buffer + (25 - temp) * 80, blank, 80);
    terminal_row = 25 - 1;
}
but even this solution doesn't work for me. I'm trying to scroll terminal simply by printing 27 numbers each in seperate line.But terminal shows only first 25 lines, and doesn't scroll. Iny ideas what I'm doing wrong?

Re: Qemu and terminal scroll problem

Posted: Sat Feb 03, 2018 5:01 am
by BrightLight
I haven't reviewed the code, but that last line is incorrect. memset() takes an integer as a pointer, but it is degraded to char when it is actually used. So you can't use memset() for writing uint16_t.
Next, I'd move the screen one-line up like this:

Code: Select all

memcpy(terminal_buffer, terminal_buffer+160, 80*24*2);
Where terminal buffer is a void* or char* pointer to 0xB8000.

Re: Qemu and terminal scroll problem

Posted: Sat Feb 03, 2018 6:12 am
by Brendan
Hi,

In addition to the "memset does 8-bit bytes and not 16-bit words" problem, there's a bug with the moving - "memcpy()" is allowed to assume that the source and destination do not overlap, which allows it to use faster implementation with fewer checks. Because your source and destination areas do overlap you should be using "memmove()" instead.

Note that the easiest way to fix the "memset()" problem is to make the buffer 1 line larger and pre-fill the extra "never modified" last row once (e.g. when clearing the buffer during initialisation); then (when you "memmove()") you can copy the "never modified, always full of space" extra row into the last row.

Mostly, the whole thing could be:

Code: Select all

void terminal_scroll(void) {
    memmove(terminal_buffer, terminal_buffer + 80*2, 80*25*2);
}
darvark wrote:But terminal shows only first 25 lines, and doesn't scroll. Iny ideas what I'm doing wrong?
You'd also need to copy the buffer to video display memory so that the changes are visible. Typically this happens later (e.g. you try to add some character/s but you're at the bottom of the screen; so you scroll, then add the character/s, then copy from the buffer to the video card's display memory).


Cheers,

Brendan

Re: Qemu and terminal scroll problem

Posted: Sat Feb 03, 2018 2:19 pm
by darvark
Brendan wrote: You'd also need to copy the buffer to video display memory so that the changes are visible. Typicaly this happens later (e.g. you try to add some character/s but you're at the bottom of the screen; so you scroll, then add the character/s, then copy from the buffer to the video card's display memory).
Hi,
Thanks for your suggestions, and about that copy buffer to display memory, as I understand this happens when I print next character to screen.