Virtual Consoles

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
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Virtual Consoles

Post 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).
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

You don't seem to be initializing your TVideoConsole.data members...
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post 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.
User avatar
t0xic
Member
Member
Posts: 216
Joined: Sat May 05, 2007 3:16 pm
Location: VA
Contact:

Post 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
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post 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);
}
User avatar
t0xic
Member
Member
Posts: 216
Joined: Sat May 05, 2007 3:16 pm
Location: VA
Contact:

Post 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
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post 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.
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post 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.
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post 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?
User avatar
t0xic
Member
Member
Posts: 216
Joined: Sat May 05, 2007 3:16 pm
Location: VA
Contact:

Post 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
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post 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?
Post Reply