OSDev.org
https://forum.osdev.org/

Problem moving message down one line
https://forum.osdev.org/viewtopic.php?f=1&t=15381
Page 1 of 1

Author:  nightfire8199 [ Sat Nov 10, 2007 1:25 pm ]
Post subject:  Problem moving message down one line

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:

#include "Video.h"

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



Video.cpp
Code:
#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:
#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

Author:  LordMage [ Sat Nov 10, 2007 3:04 pm ]
Post subject: 

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:
vid.clear()
vid.write("Hello World!/n");
vid.write("Prompt>");

Author:  AndrewAPrice [ Sat Nov 10, 2007 4:59 pm ]
Post subject: 

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

In Video::put try:
Code:
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

Author:  nightfire8199 [ Sat Nov 10, 2007 5:56 pm ]
Post subject: 

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

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


I'm not sure that makes sense to me...

Author:  JamesM [ Sun Nov 11, 2007 3:52 am ]
Post subject: 

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

Code:
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.

Author:  AJ [ Sun Nov 11, 2007 4:08 pm ]
Post subject: 

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

Author:  nightfire8199 [ Sun Nov 11, 2007 4:47 pm ]
Post subject: 

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:
#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...

Author:  Combuster [ Mon Nov 12, 2007 1:33 am ]
Post subject: 

[wiki]Text_Mode_Cursor[/wiki]

Author:  nightfire8199 [ Mon Nov 12, 2007 2:25 pm ]
Post subject: 

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....

Author:  JamesM [ Mon Nov 12, 2007 2:33 pm ]
Post subject: 

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

Author:  nightfire8199 [ Mon Nov 12, 2007 3:49 pm ]
Post subject: 

Quote:

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.

Author:  Combuster [ Mon Nov 12, 2007 3:59 pm ]
Post subject: 

...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)

Author:  frank [ Mon Nov 12, 2007 4:16 pm ]
Post subject: 

I think this might work

Code:
void outb(unsigned char port, unsigned char val)
{
asm volatile("outb %%al, %%dx" : : "d"(port), "a"(val));
}
}


EDIT: I had the parameters backwards.

Author:  nightfire8199 [ Mon Nov 12, 2007 4:45 pm ]
Post subject: 

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.

Author:  LordMage [ Tue Nov 13, 2007 6:51 am ]
Post subject: 

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

functions.h
Code:

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



functions.asm
Code:

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

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/