Weird printing 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
Qeroq
Member
Member
Posts: 52
Joined: Wed Aug 25, 2010 6:35 am
Location: Bonn, Germany

Weird printing problem

Post by Qeroq »

Hello,
as I finally tried to enter operating system development I've encountered a weird problem using the following code:

Code: Select all

struct ConsoleCell cell;

for (i = 0; i < (80 * 25); i++)
{
    cell.character = '0' + (i % 10);
    cell.attributes = 0x07;
    videomem[i] = cell;
}
with ConsoleCell defined as

Code: Select all

struct ConsoleCell
{
    char character;
    unsigned char attributes;
} __attribute__((packed));
and videomem defined as

Code: Select all

videomem = (ConsoleCell*) 0xb8000;
This code obviously is intended to fill the screen with numbers from zero to ten, but it doesn't, at least not completely:
Image

Additionally, when I try to set a random character using the following code after filling the screen, nothing happens.

Code: Select all

    struct ConsoleCell cell;
    cell.character = c;
    cell.attributes = 0x35;
    
    videomem[y * 80 + x] = cell;
In fact, the screenshot above is generated after having called the last code snippet for c='B', x=20 and y=2.

I'm compiling my code on an x86_64 using the following tools:
g++ -m32 -march=i386 -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions -Wall -Wextra
nasm -f elf32
ld -melf_i386

Qemu is used for running the resulting floppy image.
https://github.com/qero/Hydrogen (Loader for AMD64 kernels running on top of GRUB2)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Weird printing problem

Post by Combuster »

QEmu is notorious for buffering video memory. If you have a cli;hlt; somewhere in your code, replace it with a spinloop (usually, while(1); or jmp $). You can start by adding one of those at the end of your drawing code to see if that makes it do what you want.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Qeroq
Member
Member
Posts: 52
Joined: Wed Aug 25, 2010 6:35 am
Location: Bonn, Germany

Re: Weird printing problem

Post by Qeroq »

Hm, I added a while(true); to the end of my main() leading to more characters to be rendered, but there are still 11 ones missing at the lower right corner, and my 'B' does not get written at all.
Please ask, if I've missed some important information.
https://github.com/qero/Hydrogen (Loader for AMD64 kernels running on top of GRUB2)
cristian
Posts: 5
Joined: Sun Jul 25, 2010 11:41 pm

Re: Weird printing problem

Post by cristian »

Code: Select all

// Try it this way
for (i = 0; i < (80 * 25); i++)
{
    videomem[i].character = '0' + (i % 10);
    videomem[i].attributes = 0x07;
}
EDIT

Code: Select all

void putchar(u16 pos, i8 ch, u8 color)
{
    if(pos < screensize){
        videomem[pos].character = ch;
        videomem[pos].attributes = color;
    } else {
        // You ain't got no pancake mix!
    }
}
Use it like putchar(pos, 'a', 0x07);

EDIT2, 3

Code: Select all

void putchar(u16 x, u16 y, i8 ch, u8 color)
{
    if(x < 80 && y < 25){
        videomem[y*80 + x].character = ch;
        videomem[y*80 + x].attributes = color;
    } else if(y >= 25){
        // Next page?
        // You ain't got no pancake mix!
    } else {
        // You ain't got no pancake mix!
    }
}
Use it like putchar(10, 50, 'a', 0x07);
If it won't work, try using bochs.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Weird printing problem

Post by gerryg400 »

Make sure interrupts are enabled before you do the while (1) loop.

Code: Select all

   __asm__ __volatile__ ( "sti" );
   while (1)
      ;
If Qemu reaches a jmp that does not modify the instruction pointer and interrupts are disabled, it stops processing, even if there is not a hlt.
If a trainstation is where trains stop, what is a workstation ?
Qeroq
Member
Member
Posts: 52
Joined: Wed Aug 25, 2010 6:35 am
Location: Bonn, Germany

Re: Weird printing problem

Post by Qeroq »

Hello,
you have helped me very much as I was kind of going insane not being able to figure out what's wrong with my code. Bochs just does its job well, although it's always rebooting when I call sti before the infinite loop.
https://github.com/qero/Hydrogen (Loader for AMD64 kernels running on top of GRUB2)
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Weird printing problem

Post by gerryg400 »

Time to set up an IDT.
If a trainstation is where trains stop, what is a workstation ?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Weird printing problem

Post by Candy »

or, short term fix, do some pointless processing.

Code: Select all


int retval = 2937859821;
while (retval) {
   retval = retval * 2436719375 + 29864765;
}

while(1) {}
Post Reply