Problem moving message down one line

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
nightfire8199
Posts: 8
Joined: Wed Nov 07, 2007 6:33 pm

Problem moving message down one line

Post by nightfire8199 »

I used the Tutorial from www.osdever.net labeled Kernel in C++.

after following it (and noticing there is only 2 of the 4 parts) I started to implement my own code. I added a newline function but when I execute it all it does is move the next printed string one spot to the right. the tutorial says that the:

undefined int off;

should move the cursor or message down a line. but when I use my function it does not do so. It does the same thing as the pos integer (undefined int pos;)

here is ALL of my code:


Kernel.cpp

Code: Select all

 
#include "Video.h"

int main(void)
{
	Video Vid;
	Vid.write("Welcome, To Orion OS");
	Vid.cout("Orion>>");
}

Video.cpp

Code: Select all

#include "Video.h"




Video::Video()
{
	pos=0; off=0;
	videomem = (unsigned short*) 0xb8000 ;
}

Video::~Video()
{

}

void Video::clear()
{
	unsigned int i;
	for(i=0; i<(80*25); i++)
	{
		videomem[i] = (unsigned char) ' ' | 0x0700 ;
	}
	pos=0; off=0;
}

void Video::write(char *cp)
{
	char *str = cp, *ch;
	clear() ;
	pos=0; off=0;
	for (ch = str; *ch; ch++)
	{
		put(*ch) ;
		pos+=1; //off+=1;
	}

	pos; off;
}

int Video::newline()
{
	pos=0; off++;
}

void Video::cout(char *cp)
{
	char *str = cp, *ch;
	newline() ;
	for (ch = str; *ch; ch++)
	{
		put(*ch) ;
		pos+=1; //off+=1;
	}
	pos; off;
}

void Video::put(char c)
{
	if(pos>=80)
	{
		pos=0;
		off += 80;
	}
	
	if(off>=(80*25))
	{
		clear() ; //clear the screen
	}
	videomem[off + pos] = (unsigned char) c | 0x0700 ;
}

Video.h

Code: Select all

#ifndef VIDEO_H
#define VIDEO_H //only one definition of Video

class Video
{
public:
	Video();
	~Video();
	int newline();
	void clear();
	void write(char *cp);
	void cout(char *cp);
	void put(char c);
private:
	unsigned short *videomem ;
	unsigned int off ;
	unsigned int pos ;
};

#endif
linker and asm available if needed
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

okay, I noticed in your put(char c) function that you increment off by 80 so that you don't have to mulitply it at the last moment. but in your newline function you only use off++ so you are adding one to your offset. this will move the text over one character instead of down one line.

on a side note. you could use a switch statement or an if..else statement to keep an eye out for /n the newline character and run your newline function when that character is encountered. then you wouldn't require two functions for basically the same function. the same could go for your clear function. you could select a special character /C or something that when encountered would clear the screen. or you could just make a call to the function outside of your write function.

Code: Select all

vid.clear()
vid.write("Hello World!/n");
vid.write("Prompt>");
Getting back in the game.
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Post by AndrewAPrice »

Overwrite the << and >> so Video emulates a stream. It's much more C++-ish.

In Video::put try:

Code: Select all

videomem[off * 80 + pos] = (unsigned char) c | 0x0700 ; 
Since for to move down a line we have to skip 80 characters. You might be interested in reading: http://osdever.net/bkerndev/Docs/printing.htm
My OS is Perception.
nightfire8199
Posts: 8
Joined: Wed Nov 07, 2007 6:33 pm

Post by nightfire8199 »

Thanks a lot for the help...very much appreciated. It worked very well.

oh and thanks for the link.

and what do you mean when you say
Overwrite the << and >> so Video emulates a stream. It's much more C++-ish.
I'm not sure that makes sense to me...
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

In C++ normally to output to the stdout you use std::ostream, thus:

Code: Select all

std::cerr << "Hello!" << ", my name is JamesM" << std::hex << 0xdeadbaba << std::endl
What MessiahAndrw means is that you can accomplish the same thing with your Video class by overriding the operator<< and operator>> functions.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Out of interest, how do you deal with memory allocation in this? Presumably std::hex needs to allocate space for a char array and free it later, or does it just use a static array?

Cheers,
Adam
nightfire8199
Posts: 8
Joined: Wed Nov 07, 2007 6:33 pm

Post by nightfire8199 »

Ok now that I hae the newline() function working I seem to have developed a new problem...The cursor (The blinking line) does'nt seem to move as a result of the changes in pos and off...how would I go about moving the cursor. After I boot my Kernel from GRUB it just stays in whatever position it was last in. Any Ideas?

New Video.cpp code

Code: Select all

#include "Video.h"




Video::Video()
{
	pos=0; off=0;
	videomem = (unsigned short*) 0xb8000 ;
}

Video::~Video()
{

}

void Video::clear()
{
	unsigned int i;
	for(i=0; i<(80*25); i++)
	{
		videomem[i] = (unsigned char) ' ' | 0x0700 ;
	}
	pos=0; off=0;
}

void Video::write(char *cp)
{
	char *str = cp, *ch;
	clear() ;
	pos=0; off=0;
	for (ch = str; *ch; ch++)
	{
		put(*ch) ;
		pos+=1; //off+=1;
	}

	pos=20; off += 80 - pos;
}

int Video::newline()
{
	pos=0; off += 100 - pos;
}

void Video::cout(char *cp)
{
	char c;
	char *str = cp, *ch;
	newline() ;
	videomem[off * 80 + pos] = (unsigned char) c | 0x0700 ;
	for (ch = str; *ch; ch++)
	{
		put(*ch) ;
		pos+=1; //off+=1;
	}
	
//	pos; off;
}

void Video::put(char c)
{
	
	if(pos>=80)
	{
		pos=0;
		off += 80;
	}
	
	if(off>=(80*25))
	{
		clear() ; //clear the screen
	}
	videomem[off + pos] = (unsigned char) c | 0x0700 ;
}
Rest of code on top...once again asm and ld available upon request...
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:

Post by Combuster »

"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 ]
nightfire8199
Posts: 8
Joined: Wed Nov 07, 2007 6:33 pm

Post by nightfire8199 »

after adding the code to my video driver it now says that outb is not declared...after much trying i looked about at other tutorials, they do not declare it either....

So...confusing....
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Code: Select all

void outb(unsigned char port, unsigned char val)
{
  asm volatile("outb %0, %1" : : "r"(port), "r"(val));
}
nightfire8199
Posts: 8
Joined: Wed Nov 07, 2007 6:33 pm

Post by nightfire8199 »


void outb(unsigned char port, unsigned char val)
{
asm volatile("outb %0, %1" : : "r"(port), "r"(val));
}


Error: suffix or operands invalid for `out'

sorry not very accustom to assembly.
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:

Post by Combuster »

...other than allowing gcc to pick two registers at will where it can not...

the instructions you should have are

out dx, al
out dx, ax
out dx, eax
(in order: outb, outw, outl)
in al, dx
in ax, dx
in eax, dx
(inb, inw, inl)
But I suck at GCC inline assembly so I can't give the correct implementation.

I do have implementations (with different names) that you can use. you'll need nasm/yasm to assemble them though. (corresponding C header file)
"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 ]
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

I think this might work

Code: Select all

void outb(unsigned char port, unsigned char val)
{
asm volatile("outb %%al, %%dx" : : "d"(port), "a"(val));
}
}
EDIT: I had the parameters backwards.
nightfire8199
Posts: 8
Joined: Wed Nov 07, 2007 6:33 pm

Post by nightfire8199 »

it compiles nicely, yet it seems to do nothing. the cursor is still WAY at the bottom...hmmm...Is it possible to call functions declared in a ASM file?
if so there may be a way.
LordMage
Member
Member
Posts: 115
Joined: Sat Sep 22, 2007 7:26 am
Contact:

Post by LordMage »

Yes there is, I am not sure for GCC but it requires the following syntax in Visual C++

functions.h

Code: Select all


extern "C" void _cdecl outb(unsigned char port, unsigned char val);

functions.asm

Code: Select all


global _outb

_outb:
     out dx, al
     ret


I use NASM and VC++ so I would compile the ASM file with the following

C:\OS Design\nasm -f win32 functions.h

then I have to make sure and add the resulting functions.obj to my project. I know it will be slightly differrent for you but the ability is there. check out brans tutorial on osdever.net for a way to do the same thing using NASM and GCC. good luck
Getting back in the game.
Post Reply