Page 1 of 1

Virtual Consoles

Posted: Tue Jun 05, 2007 1:30 am
by jzgriffin
Hey, I'm having some trouble with virtual consoles. What I think is happening is that the data isn't being properly stored in the TVirtualConsole.data variable, but I can't figure out how to fix it.

video.c:

Code: Select all

/* Includes */
#include <hardware.h>
#include <memory.h>
#include <video.h>

/* Variables */
TVideoConsole videoConsoles[9];
int currentConsole;

/**
 * Description:
 *     Initializes the virtual consoles.
 *
 * Parameters:
 *
 * Result:
 *
 */
void VideoInitialize()
{
    int index;

    for(index = 0; index < 9; index++)
    {
        videoConsoles[index].color = 0x07;
        videoConsoles[index].memory = (unsigned char *)0xB8000;
        videoConsoles[index].x = 0;
        videoConsoles[index].y = 0;
        ClearScreen(' ', 0x07, index);
    }

    currentConsole = 0;
}

/**
 * Description:
 *     Changes virtual consoles.
 *
 * Parameters:
 *     console - ID of the new virtual console to switch to.
 *
 * Result:
 *
 */
void SwitchConsoles(int console)
{
    unsigned char *where;
    int index;

    currentConsole = console;

    MemorySet(
        videoConsoles[console].memory,
        videoConsoles[console].data,
        4160
    );
    /*MemoryCopy(
        videoConsoles[console].data,
        videoConsoles[console].memory,
        sizeof(videoConsoles[console].data)
    );*/

    VideoUpdateCursor(console);
}

/**
 * Description:
 *     Changes the color for new characters printed to console.
 *
 * Parameters:
 *     color - New color value.
 *     console - Console that will be modified.
 *
 * Result:
 *
 */
void SetVideoColor(unsigned char color, int console)
{
    videoConsoles[console].color = color;
}

/**
 * Description:
 *     Clears the screen of all data.
 *
 * Parameters:
 *     character - Character to clear the screen with.
 *     color - Color to print the character in.
 *     console - Console to clear.
 *
 * Result:
 *
 */
void ClearScreen(unsigned char character, unsigned char color, int console)
{
    unsigned char oldColor;
    int index;

    oldColor = videoConsoles[console].color;
    SetVideoColor(color, console);

    for(
        index = 0;
        (videoConsoles[console].x != 80) && (videoConsoles[console].y != 25);
        index++
    )
        PrintChr(character, console);

    SetVideoColor(oldColor, console);
    videoConsoles[console].x = 0;
    videoConsoles[console].y = 0;

    return;
}

/**
 * Description:
 *     Prints a character to the screen.
 *
 * Parameters:
 *     character - Character to print.
 *     console - Console to output to.
 *
 * Result:
 *
 */
void PrintChr(const unsigned char character, int console)
{
    unsigned char *where = (unsigned char *)(0xB8000 + (
            videoConsoles[console].y *
            80 +
            videoConsoles[console].x
        ) * 2
    );

    *videoConsoles[console].data++ = character;
    *videoConsoles[console].data++ = videoConsoles[console].color;
    /*videoConsoles[console].data[(
            videoConsoles[console].y *
            80 +
            videoConsoles[console].x
        ) * 2
    ] = character;
    videoConsoles[console].data[(
            videoConsoles[console].y *
            80 +
            videoConsoles[console].x + 1
        ) * 2
    ] = videoConsoles[console].color;*/

    //if(console != currentConsole)
    //{
    //    return;
    //}

    if(character >= ' ')
    {
        *where++ = character;
        *where++ = videoConsoles[console].color;
        videoConsoles[console].x++;
        if(videoConsoles[console].x == 80)
        {
            videoConsoles[console].y++;
            videoConsoles[console].x = 0;
        }
    }
    else
    {
        switch(character)
        {
        case('\n'):
            {
                videoConsoles[console].x = 0;
                videoConsoles[console].y++;
            }
            break;
        case('\r'):
            {
                videoConsoles[console].x = 0;
            }
            break;
        case('\t'):
            {
                videoConsoles[console].x = videoConsoles[console].y + 8;
            }
            break;
        case(0x08):
            {
                if(videoConsoles[console].x != 0)
                    videoConsoles[console].x--;
            }
            break;
        }
    }

    //VideoScroll(console);
    VideoUpdateCursor(console);
}

/**
 * Description:
 *     Prints a string to the screen.
 *
 * Parameters:
 *     string - String to print.
 *     console - Console to print to.
 *
 * Result:
 *
 */
void PrintStr(char *string, int console)
{
    for(; *string != '\0'; string++)
        PrintChr(*string, console);
}

/**
 * Description:
 *     Updates the hardware cursor.
 *
 * Parameters:
 *     console - Console to update.
 *
 * Result:
 *
 */
void VideoUpdateCursor(int console)
{
    unsigned where;

    where = videoConsoles[console].y * 80 + videoConsoles[console].x;

    HwWriteByte(0x3D4, 14);
    HwWriteByte(0x3D5, where >> 8);
    HwWriteByte(0x3D4, 15);
    HwWriteByte(0x3D5, where);
}

/**
 * Description:
 *     Scrolls the screen down to fit all of the text.
 *
 * Parameters:
 *
 * Result:
 *
 */
void VideoScroll()
{
    //
}
video.h:

Code: Select all

/* Inclusion guard */
#ifndef __VIDEO_H__
#define __VIDEO_H__

/* Structures */
typedef struct
{
    unsigned char color, *data, *memory;
    unsigned x, y;
} TVideoConsole, *PVideoConsole;

/* Variables */
extern TVideoConsole videoConsoles[9];
extern int currentConsole;

/* Routines */
extern void VideoInitialize();
extern void SwitchConsoles(int console);
extern void SetVideoColor(unsigned char color, int console);
extern void ClearScreen(
    unsigned char character,
    unsigned char color,
    int console
);
extern void PrintChr(const unsigned char character, int console);
extern void PrintStr(char *string, int console);
extern void VideoUpdateCursor(int console);
extern void VideoScroll();

#endif /* __VIDEO_H__ */
I'm completely stumped, already tried like 20 little fixes that have failed. Also, about the commented out IF block in PrintChr, no text prints when that is uncommented. At all. Some, or a lot, of help would be greatly appreciated.

Thanks!
- Jeremiah

P.S.: I'm not aiming for POSIX compatibility, or compatibility with any other OS. That is why I've strayed so far from traditional function names (e.g. putc).

Posted: Tue Jun 05, 2007 4:09 am
by urxae
You don't seem to be initializing your TVideoConsole.data members...

Posted: Tue Jun 05, 2007 9:44 am
by jzgriffin
Could you please elaborate a bit more on how I would go about this? I've tried both MemorySet and a for loop, and neither gets the desired output.

Posted: Tue Jun 05, 2007 5:00 pm
by t0xic
In your VideoInit() Function, make sure you put a value into the videoConsole[index].data variable.

ex:

Code: Select all

videoConsole[index].data = (char*)0;
etc,

Also, might I suggest having a pointer to the current console so for each function you dont have to specify which console and can access it using consPtr.memory, .data, etc

Code: Select all


TVideoConsole *consPtr;

Code: Select all

void SwitchConsoles(int console)
{

    
    unsigned char *where;
    int index;
    consPtr = &videoConsole[console];
    currentConsole = console;

    MemorySet(
        videoConsoles[console].memory,
        videoConsoles[console].data,
        4160
    );
    /*MemoryCopy(
        videoConsoles[console].data,
        videoConsoles[console].memory,
        sizeof(videoConsoles[console].data)
    );*/

    VideoUpdateCursor(console);
} 
Just my thoughts on this,

--t0xic

Posted: Tue Jun 05, 2007 8:36 pm
by jzgriffin
Thanks, but the problem still persists. Whenever I call SwitchConsoles, a lot of black on red L's will be printed out continually. Is my call to MemorySet the problem?

Edit: I changed MemorySet to MemoryCopy, and now I'm a bit closer. When I call SwitchConsoles(2) after printing the build date to it, it displays something that isn't entirely random: Part of console #1. Blanks followed by "NovaOS 2008[random]"

Edit2: Now I'm using PrintChr to print it, and the data is semi-correct. On a somewhat blank screen, gibberish will be printed instead of blanks, though. And I still can't figure out how to get the commented if in PrintChr to work (whenever enabled, no data prints, even after some modification). New code:

Code: Select all

/**
 * Copyright (C) 2007, Niantec Corporation
 *
 * Description:
 *     Video input/output routines, such as PrintStr.
 *
 * Created:
 *     By Jeremiah Griffin (jeremiahzg) on 2007-06-04
 *
 * History:
 *
 */

/* Includes */
#include <hardware.h>
#include <memory.h>
#include <video.h>

/* Variables */
TVideoConsole videoConsoles[9];
int currentConsole;

/**
 * Description:
 *     Initializes the virtual consoles.
 *
 * Parameters:
 *
 * Result:
 *
 */
void VideoInitialize()
{
    int index;

    for(index = 0; index < 9; index++)
    {
        videoConsoles[index].color = 0x07;
        videoConsoles[index].data = (unsigned char *)0;
        videoConsoles[index].memory = (unsigned char *)0xB8000;
        videoConsoles[index].x = 0;
        videoConsoles[index].y = 0;
        ClearScreen(' ', 0x07, index);
    }

    currentConsole = 1;
}

/**
 * Description:
 *     Changes virtual consoles.
 *
 * Parameters:
 *     console - ID of the new virtual console to switch to.
 *
 * Result:
 *
 */
void SwitchConsoles(int console)
{
    //unsigned char *where = (unsigned char *)0xB8000;
    int index;

    currentConsole = console;

    //MemoryCopy(
    //    videoConsoles[console].memory,
    //    videoConsoles[console].data,
    //    4160
    //);

    index = 0;
    while(index <= 4160)
    {
        SetVideoColor(index + 1, console);
        PrintChr(index, console);

        index += 2;
    }

    VideoUpdateCursor(console);
}

/**
 * Description:
 *     Changes the color for new characters printed to console.
 *
 * Parameters:
 *     color - New color value.
 *     console - Console that will be modified.
 *
 * Result:
 *
 */
void SetVideoColor(unsigned char color, int console)
{
    videoConsoles[console].color = color;
}

/**
 * Description:
 *     Clears the screen of all data.
 *
 * Parameters:
 *     character - Character to clear the screen with.
 *     color - Color to print the character in.
 *     console - Console to clear.
 *
 * Result:
 *
 */
void ClearScreen(unsigned char character, unsigned char color, int console)
{
    unsigned char oldColor;
    int index;

    oldColor = videoConsoles[console].color;
    SetVideoColor(color, console);

    for(
        index = 0;
        (videoConsoles[console].x != 80) && (videoConsoles[console].y != 25);
        index++
    )
        PrintChr(character, console);

    SetVideoColor(oldColor, console);
    videoConsoles[console].x = 0;
    videoConsoles[console].y = 0;

    return;
}

/**
 * Description:
 *     Prints a character to the screen.
 *
 * Parameters:
 *     character - Character to print.
 *     console - Console to output to.
 *
 * Result:
 *
 */
void PrintChr(const unsigned char character, int console)
{
    unsigned char *where = (unsigned char *)(0xB8000 + (
            videoConsoles[console].y *
            80 +
            videoConsoles[console].x
        ) * 2
    );

    *videoConsoles[console].data++ = character;
    *videoConsoles[console].data++ = videoConsoles[console].color;

    //if(console != currentConsole)
    //{
        if(character >= ' ')
        {
            *where++ = character;
            *where++ = videoConsoles[console].color;
            videoConsoles[console].x++;
            if(videoConsoles[console].x == 80)
            {
                videoConsoles[console].y++;
                videoConsoles[console].x = 0;
            }
        }
        else
        {
            switch(character)
            {
            case('\n'):
                {
                    videoConsoles[console].x = 0;
                    videoConsoles[console].y++;
                }
                break;
            case('\r0'):
                {
                    videoConsoles[console].x = 0;
                }
                break;
            case('\t'):
                {
                    videoConsoles[console].x = videoConsoles[console].y + 8;
                }
                break;
            case(0x08):
                {
                    if(videoConsoles[console].x != 0)
                        videoConsoles[console].x--;
                }
                break;
            }
        }

        VideoUpdateCursor(console);
    //}
}

/**
 * Description:
 *     Prints a string to the screen.
 *
 * Parameters:
 *     string - String to print.
 *     console - Console to print to.
 *
 * Result:
 *
 */
void PrintStr(char *string, int console)
{
    for(; *string != '\0'; string++)
        PrintChr(*string, console);
}

/**
 * Description:
 *     Updates the hardware cursor.
 *
 * Parameters:
 *     console - Console to update.
 *
 * Result:
 *
 */
void VideoUpdateCursor(int console)
{
    unsigned where;

    where = videoConsoles[console].y * 80 + videoConsoles[console].x;

    HwWriteByte(0x3D4, 14);
    HwWriteByte(0x3D5, where >> 8);
    HwWriteByte(0x3D4, 15);
    HwWriteByte(0x3D5, where);
}

Posted: Wed Jun 06, 2007 2:03 pm
by t0xic
I see a problem in your SwitchConsoles code:

Code: Select all

while(index <= 4160)
    {
        SetVideoColor(index + 1, console);
        PrintChr(index, console);

        index += 2;
    }
each value of (index) 4160 times

When you switch consoles just call this:

Code: Select all

memcpy( (void*)0xb8000, (void*)videoConsoles[index].mem, 4000 );
That will move the data directly to the video ram, instead of calling another function

Good luck

--t0xic

Posted: Thu Jun 07, 2007 6:20 pm
by jzgriffin
Thanks, but now the SwitchConsoles function simply display all-wrong output, as before when I used MemoryCopy (read the commented out code). Also, as I mentioned, why doesn't the commented if statement in PrintChr ever return true? No data is printed whatsoever when it is enabled.

Posted: Fri Jun 08, 2007 2:23 am
by urxae
When I said you should initialize your .data members, I didn't mean all to the same address, and probably not all to NULL either. Either initialize each to the result of [k]malloc(4160)[1] (called separately each time, of course) or just change its type from unsigned char* to unsigned char[4160] to allocate it statically.


[1]: That seems to be the amount of data you use from it.

Posted: Tue Jun 12, 2007 1:52 pm
by jzgriffin
Thanks for all of the help, I finally understand how to fix them...the only problem is: Why doesn't the commented-out if statement in PrintChr ever return true?

Posted: Tue Jun 12, 2007 2:22 pm
by t0xic
@Jeremiah: If I am correct, that is a good thing that the PrintChr commented out section returns false. That would be an error if it didnt, right?

--t0xic

Posted: Tue Jun 12, 2007 2:41 pm
by jzgriffin
What I mean by that is, whenever I check console to see if it is equal to currentConsole, the if never continues to the contents of it's block. It just skips it and no output is printed. I have even tried using different operators for checking the two values: ==, !=, >, <, >=, <=, and it never gets the desired output.

Who knew that such a simple if statement could stall the progress of an operating system's development?