Page 1 of 1

Cursor position

Posted: Sat Sep 27, 2003 12:47 pm
by pytrood
Hi!
How do I get & set the position of the cursor (textcursor)?

Re:Cursor position

Posted: Sat Sep 27, 2003 9:49 pm
by Perica
..

Re:Cursor position

Posted: Sun Sep 28, 2003 9:08 pm
by rdragon
You will probably be most interested in reading and writing from IO ports

0x3D4 and 0x3D5

That should be all the help you need. Look up how the ports work and try to implement some goodness :)

Re:Cursor position

Posted: Mon Sep 29, 2003 4:04 am
by Pype.Clicker
keep in mind that reading/writing through ports is a considerably sloooow operation on modern computers. so i would recommend you
  • to cache the last value of the cursor position in some static variable, so that you only have to read it once
  • not to update the cursor at every displayed char, but rather only when you're done with a whole string or something alike. Of course, this should not apply when the user types a character, as the user is considerably sloooooower than I/O operations anyway ;D
  • to hide the cursor as long as no user input is expected.

Re:Cursor position

Posted: Wed Oct 01, 2003 11:36 am
by Tonda
char getxpos(void)
{
_AH = 0x03;
_BH = 0x00;

asm int 0x10

return _DL;
}

char getypos(void)
{
_AH = 0x03;
_BH = 0x00;

asm int 0x10

return _DH;
}

void gotoxy(char x, char y)
{
asm mov bh, 0
asm mov ah, 0x02
asm mov dl, x
asm mov dh, y

asm int 0x10
}

Re:Cursor position

Posted: Wed Oct 01, 2003 5:26 pm
by pytrood
I'm having some problems with the GCC inline ASM.
This is my code:

Code: Select all

void kconsoleGoto(char _X, char _Y) {
   asm("mov $0,   %bh      \n\t
       mov %0,   %dl      \n\t 
       mov %1,   %dh      \n\t" : : "0" (_X), "1" (_Y));

   asm("int 0x10");
      
}
The error I get is "Matching constraint references invalid operand number", hmm.... :/

Re:Cursor position

Posted: Thu Oct 02, 2003 1:46 am
by Pype.Clicker
the problem comes from "0" and "1". GCC expects you to provide arguments of an ASM command in the form "<hint>"(var), where <hint> tells it in what it should store the argument (like "a"(x) to force x to be stored in register eax, "m"(x) to force it to be a memory reference, "g"(x) to let the compiler decide).

So asm("mov %0,%%edx"::"a"(x)) translates into "movl %eax,%edx" (and the compiler makes sure the value of X is in %eax before issuing this instruction),
asm("mov %0,%%edx"::"m"(x)) translates into "movl address_of_x,%edx" (note that i wrote "address_of_x", which is a memory reference, and not $address_of_x, which would be an immediate constant ;] )
asm("mov %0,%%edx"::"r"(x)) translates into "movl <register>,%edx" (and lets the compiler decide which register it will use)
asm("mov %0,%%edx"::"g"(x)) leaves the compiler completely free on what x will be, provided that it is moved into edx.

Note that as a general rule,

Code: Select all

asm("mov %0,%%edx; " OTHER_OPERATIONS:"g"(x));
can be rewritten as

Code: Select all

asm(OTHER_OPERATIONS:"d"(x));

Code: Select all

void kconsoleGoto(char _X, char _Y) {
   asm("mov $0,   %%bh      \n\t
       mov %0,   %%dl      \n\t
       mov %1,   %%dh      \n\t int 0x10\n\t" : : "g" (_X), "g" (_Y));
      }
should do the trick, but ask yourself this question:
Why do you want to issue a BIOS call -- which is for 16 bits realmode only -- in a 32 bits compiler ? Except if you programmed your compiler in a really really strange way, you should not do this at all and rather use direct port access.