OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 4:13 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:21 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
For a shell, I need a part of a function get the cursor position.

However, I can't find any documentation or code that shows how i can get the cursor position.
How do I get this?

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:24 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
http://wiki.osdev.org/Text_Mode_Cursor


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:25 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
iansjack wrote:
http://wiki.osdev.org/Text_Mode_Cursor

I meant get the cursor location/position, not setting it. I already have a function that sets the cursor.

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:27 am 
Offline
Member
Member
User avatar

Joined: Tue Aug 02, 2016 1:52 pm
Posts: 286
Location: East Riding of Yorkshire, UK
Why do you need to get it again? Why not just store the position of the cursor in your code?

_________________
com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
Compiler Development Forum


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:28 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
I've been following your train-wreck on #osdev. You don't listen so there is little point in anyone wasting their time to help you.

One last try. The text cursor is at 0, 0 until you put it somewhere else. And then you know where it is.


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:34 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
zenzizenzicube wrote:
Why do you need to get it again? Why not just store the position of the cursor in your code?

Yep, I should do that.

EDIT: Got it, but i get a space character every time i release a key.

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:46 am 
Offline
Member
Member

Joined: Wed Jan 11, 2017 3:29 pm
Posts: 27
Use INT 10h. Go to Wikipedia. That's a nice reference. Learn Assembly instead! C is useless. Assembly is great. Look how many good projects are written 100% fully in Assembly.


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 6:50 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
TheDev100 wrote:
Use INT 10h. Go to Wikipedia. That's a nice reference. Learn Assembly instead! C is useless. Assembly is great. Look how many good projects are written 100% fully in Assembly.


I'm in Protected Mode (you can't use int 10h) and thanks but I'm not switching to Assembly, i prefer C/C++.

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 7:06 am 
Offline

Joined: Thu Jan 05, 2017 12:20 pm
Posts: 1
In case you do not know how to print a character, read the following.
In case you already know how to print a character, still read the following.

0xB8000 | character at (0, 0) |
0xB8001 | color of character at (0, 0) |
0xB8002 | character at (1, 0) |
0xB8003 | color of character at (1, 0) |
0xB8004 | character at (2, 0) |
0xB8005 | color of character at (2, 0) |
0xB8006 | character at (3, 0) |
0xB8007 | color of character at (3, 0) |
.
.
.

To improve performance, you should store the cursor's position in two variables and update the cursor whenever necessary. By doing so, we will avoid reading from the controller. Also when you are OS starts, you would want to start printing text from (0, 0) right?

Code:
int x = 0, y = 0;


If you observe the memory layout I posted at the start, you can derive the following formula which tells you the memory location where the character at (x, y) is stored:

location = 0xB8000 + (y*80 + x)*2

Why 80? There are 80 characters per line.
Why 2? The first byte is used to store the character and the next byte is used to store the color/attribute. So each character takes up two bytes.

You would want to have a common color for all characters, so you store the color information it in a variable.
Code:
static uint8_t attribute = 0x0F;


To display a character on the screen, all you have to do is write to the correct memory location. Nothing to do with the hardware.

Code:
static void putc(unsigned char c)
{   
     uint16_t *where = 0xB8000 + (y *80 + x);
     *where = c | (attribute << 8);
   
      x++;
      if(x == 80)
      {
           x = 0;
           y++;
      }
}


x, y always has the position of the next character to be printed.

Where should the cursor appear?

"Hiiiiiiiii_"
..........^ the cursor should appear in the location of the next character to be printed

so that means that x, y are essentially storing the cursor's new position.

Unlike displaying characters on screen, the cursor has to be updated by talking to the CRT controller using the in/out instruction.
The controller accepts the position as:

cursor position = y*80 + x

25*80 = 2000, this would mean the cursor position cannot be stored in a byte. You'd need at least two bytes.

Unfortunately, you cannot send two bytes of data in a single out instruction to the CRT controller. You have to split it into two bytes and send separately.

Code:
unsigned int temp = y * 80 + x;

    outportb(0x3D4, 0xE);
    outportb(0x3D5, temp >> 8);
    outportb(0x3D4, 0xF);
    outportb(0x3D5, temp);


So everytime you print a character, you must update the cursor.

The final code would look something like this:

Code:
static void putc(unsigned char c)
{   
     uint16_t *where = 0xB8000 + (y *80 + x);
     *where = c | (attribute << 8);
   
      x++;
      if(x == 80)
      {
           x = 0;
           y++;
      }
      unsigned int temp = y * 80 + x;

      outportb(0x3D4, 0xE);
      outportb(0x3D5, temp >> 8);
      outportb(0x3D4, 0xF);
      outportb(0x3D5, temp);
}


You'll never need to read the location from the controller because you already have it :)
You might also want to update the cursor when your OS starts so that it moves to zero (in case it had been moved somewhere else by the bootloader or BIOS or whatever). Might also want to clear the screen? That is for you to write after reading this post (fill the screen with spaces).

The code I gave does not handle null character, carriage return, backspace, etc. Here is a better (more complete) version of the same.
Code:
static void putc(unsigned char c)
{   
   switch(c)
   {
      case '\0': return;
      case '\b':
         if(curPos_x != 0) curPos_x--;
      break;
      
      case ' ':
         curPos_x++;
      break;
      
      case '\t':
         curPos_x = (curPos_x + 8) & ~(8 - 1);
      break;
      
      case '\r':
         curPos_x = 0;
      break;
      
      case '\n':
         curPos_x = 0;
         curPos_y++;
      break;
      
      default:
      {
         if(isprint(c))
         {
            uint16_t *where = vmemptr + (curPos_y * TEXTMODE_MAX_X + curPos_x);
            *where = c | (attribute << 8);
            curPos_x++;
         }
         break;
      }
   }   
   if(curPos_x >= TEXTMODE_MAX_X)
    {
        curPos_x = 0;
        curPos_y++;
    }   
    if(curPos_y >= TEXTMODE_MAX_Y)
    {
      uint16_t blank = 0x20 | (attribute << 8);
        uint16_t temp = curPos_y - TEXTMODE_MAX_Y + 1;
        memcpy (vmemptr, vmemptr + temp * TEXTMODE_MAX_X, (TEXTMODE_MAX_Y - temp) * TEXTMODE_MAX_X * 2);
        memsetw (vmemptr + (TEXTMODE_MAX_Y - temp) * TEXTMODE_MAX_X, blank, TEXTMODE_MAX_X);
        curPos_y = TEXTMODE_MAX_Y - 1;
    }
   updatecursor();
}


When you are printing strings, you should update the cursor only once. Not every time you print a character. So instead of having update cursor in putc, add it in your puts.


Last edited by ThinkingMind on Sun Jan 15, 2017 7:14 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 7:12 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
ThinkingMind wrote:
In case you do not know how to print a character, read the following.
In case you already know how to print a character, still read the following.

0xB8000 | character at (0, 0) |
0xB8001 | color of character at (0, 0) |
0xB8002 | character at (1, 0) |
0xB8003 | color of character at (1, 0) |
0xB8004 | character at (2, 0) |
0xB8005 | color of character at (2, 0) |
0xB8006 | character at (3, 0) |
0xB8007 | color of character at (3, 0) |
.
.
.

To improve performance, you should store the cursor's position in two variables and update the cursor whenever necessary. By doing so, we will avoid reading from the controller. Also when you are OS starts, you would want to start printing text from (0, 0) right?

Code:
int x = 0, y = 0;


If you observe the memory layout I posted at the start, you can derive the following formula which tells you the memory location where the character at (x, y) is stored:

location = 0xB8000 + (y*80 + x)*2

Why 80? There are 80 characters per line.
Why 2? The first byte is used to store the character and the next byte is used to store the color/attribute. So each character takes up two bytes.

You would want to have a common color for all characters, so you store the color information it in a variable.
Code:
static uint8_t attribute = 0x0F;


To display a character on the screen, all you have to do is write to the correct memory location. Nothing to do with the hardware.

Code:
static void putc(unsigned char c)
{   
     uint16_t *where = 0xB8000 + (y *80 + x);
     *where = c | (attribute << 8);
   
      x++;
      if(x == 80)
      {
           x = 0;
           y++;
      }
}


x, y always has the position of the next character to be printed.

How should the cursor appear?

"Hiiiiiiiii_"
...........^ the cursor should appear in the location of the next character to be printed

so that means that x, y are essentially storing the cursor's new position.

Unlike displaying characters on screen, the cursor has to be updated by talking to the CRT controller using the in/out instruction.
The controller accepts the position as:

cursor position = y*80 + x

25*80 = 2000, this would mean the cursor position cannot be stored in a byte. You'd need at least two bytes.

Unfortunately, you cannot send two bytes of data in a single out instruction to the CRT controller. You have to split it into two bytes and send separately.

Code:
unsigned int temp = y * 80 + x;

    outportb(0x3D4, 0xE);
    outportb(0x3D5, temp >> 8);
    outportb(0x3D4, 0xF);
    outportb(0x3D5, temp);


So everytime you print a character, you must update the cursor.

The final code would look something like this:

Code:
static void putc(unsigned char c)
{   
     uint16_t *where = 0xB8000 + (y *80 + x);
     *where = c | (attribute << 8);
   
      x++;
      if(x == 80)
      {
           x = 0;
           y++;
      }
      unsigned int temp = y * 80 + x;

      outportb(0x3D4, 0xE);
      outportb(0x3D5, temp >> 8);
      outportb(0x3D4, 0xF);
      outportb(0x3D5, temp);
}


You'll never need to read the location from the controller because you already have it :)

The code I gave does not handle null character, carriage return, backspace, etc. Here is a better (more complete) version of the same.
Code:
static void putc(unsigned char c)
{   
   switch(c)
   {
      case '\0': return;
      case '\b':
         if(curPos_x != 0) curPos_x--;
      break;
      
      case ' ':
         curPos_x++;
      break;
      
      case '\t':
         curPos_x = (curPos_x + 8) & ~(8 - 1);
      break;
      
      case '\r':
         curPos_x = 0;
      break;
      
      case '\n':
         curPos_x = 0;
         curPos_y++;
      break;
      
      default:
      {
         if(isprint(c))
         {
            uint16_t *where = vmemptr + (curPos_y * TEXTMODE_MAX_X + curPos_x);
            *where = c | (attribute << 8);
            curPos_x++;
         }
         break;
      }
   }   
   if(curPos_x >= TEXTMODE_MAX_X)
    {
        curPos_x = 0;
        curPos_y++;
    }   
    if(curPos_y >= TEXTMODE_MAX_Y)
    {
      uint16_t blank = 0x20 | (attribute << 8);
        uint16_t temp = curPos_y - TEXTMODE_MAX_Y + 1;
        memcpy (vmemptr, vmemptr + temp * TEXTMODE_MAX_X, (TEXTMODE_MAX_Y - temp) * TEXTMODE_MAX_X * 2);
        memsetw (vmemptr + (TEXTMODE_MAX_Y - temp) * TEXTMODE_MAX_X, blank, TEXTMODE_MAX_X);
        curPos_y = TEXTMODE_MAX_Y - 1;
    }
   updatecursor();
}


When you are printing strings, you should update the cursor only once. Not every time you print a character. So instead of having update cursor in putc, add it in your puts.


I already created my own functions, i only need that character to not appear.

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 7:14 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
You are printing the release scancode. As you haven't allowed for this it is printing a random character, which happens to be blank.


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 7:28 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
iansjack wrote:
You are printing the release scancode. As you haven't allowed for this it is printing a random character, which happens to be blank.


I know that, but I don't know what the release scancode is (it's neither 0x80 or 0x81).

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 7:30 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
http://wiki.osdev.org/PS2_Keyboard


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 7:38 am 
Offline
Member
Member
User avatar

Joined: Tue Jan 10, 2017 3:19 pm
Posts: 84
If you mean the characters above 0x80, this does not work (scancode < 0x80 doesn't work).

_________________
(not so frequently updated) Code is at:

https://github.com/NunoLava1998/DixiumOS-1


Top
 Profile  
 
 Post subject: Re: How do i read/get the cursor position?
PostPosted: Sun Jan 15, 2017 8:31 am 
Offline
Member
Member

Joined: Wed Jun 17, 2015 9:40 am
Posts: 501
Location: Athens, Greece
Hi,


iansjack wrote:
I've been following your train-wreck on #osdev. You don't listen so there is little point in anyone wasting their time to help you.
And not only that, he is ungrateful we try to help him. He even went and spammed the channel.

I've decided to stop trying to help him anymore - he clearly needs to mature first.


Regards,
glauxosdever


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Majestic-12 [Bot] and 220 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group