Page 1 of 1

Cursor not moving

Posted: Thu Feb 18, 2010 3:23 pm
by claesson92
I'm trying to write a simple putchar function, and functions for moving the cursor. The cursor doesn't move at all though. Here is what i got:

Code: Select all

#include "ports.h"
#include "video.h"

unsigned char color_fg = WHITE;
unsigned char color_bg = BLACK;

unsigned short cursor_xpos = 0;
unsigned short cursor_ypos = 0;

unsigned short screen_cols = 80;
unsigned short screen_rows = 25;

void set_fgcolor(unsigned char fg)
{
	color_bg = fg;
}

void set_bgcolor(unsigned char bg)
{
	color_bg = bg;
}

unsigned char get_fgcolor()
{
	return color_fg;
}

unsigned char get_bgcolor()
{
	return color_bg;
}

int get_color()
{
	return (color_bg << 4) | (color_fg & 0x0F);
}

void move_hw_cursor(unsigned short x, unsigned short y)
{
	unsigned short position = (y * screen_cols) + x;
	
	outb(0x3D4, 0x0F);
    outb(0x3D5, (unsigned char)(position&0xFF));
    outb(0x3D4, 0x0E);
    outb(0x3D5, (unsigned char )((position>>8)&0xFF));
}

void gotoX(unsigned short x)
{
	cursor_xpos = x;
	update_hw_cursor();
}

void gotoY(unsigned short y)
{
	cursor_ypos = y;
	update_hw_cursor();
}

void gotoXY(unsigned short x, unsigned short y)
{
	gotoX(x);
	gotoY(y);
}

unsigned short getX()
{
	return cursor_xpos;
}

unsigned short getY()
{
	return cursor_ypos;
}

void update_hw_cursor()
{
	move_hw_cursor(getX(), getY());
}

unsigned short get_position()
{
	return (getY() * screen_cols) * getX();
}

void putc(const char c)
{
	// Read cursor position
	unsigned short offset = get_position();
	unsigned char *vidmem = (unsigned char *)0xB8000;
	vidmem += (offset * 2);
	
	*vidmem = c;
	*++vidmem = get_color();
	
	increment_cursor();
}

void increment_cursor()
{
	if(getX() == 79)
	{
		gotoX(0);
		gotoY(getY() + 1);
	}
	else
	{
		gotoX(getX() + 1);
	}
}

void cls()
{
  unsigned char *vidmem = (unsigned char *)0xB8000;

  // Clear visible video memory
  long loop;
  for(loop = 0; loop < (screen_rows * screen_cols); loop++)
  {
    *vidmem++ = 0;
    *vidmem++ = 0xF;
  }

	gotoXY(0, 0);
}
Why isn't my cursor moving?

Re: Cursor not moving

Posted: Thu Feb 18, 2010 3:56 pm
by Gigasoft
Well, where's the code for increment_cursor?

Re: Cursor not moving

Posted: Thu Feb 18, 2010 4:40 pm
by claesson92
Gigasoft wrote:Well, where's the code for increment_cursor?
Sorry, missed parts of the file. The code in the first post is fixed.

Re: Cursor not moving

Posted: Thu Feb 18, 2010 8:21 pm
by bitshifter
First i see this...

Code: Select all

unsigned short get_position()
{
   return (getY() * screen_cols) * getX();
}
But you want to add x, right?

Code: Select all

 offset = y * 80 + x
Trick:
y shl 4 = y * 16
y shl 6 = y * 64
add them up = y * 80
Look mom, no multiply!

Also keep close eye on variable sizes!

Re: Cursor not moving

Posted: Sat Feb 20, 2010 10:40 am
by Synon
I've had problems doing this before, but for me, it was because I was sending bytes in the wrong order. This is how I do it:

Code: Select all

/* term_update_cursor: update the hardware cursor */
void term_update_cursor(void)
{
    if (term.buffer == NULL)
        term_init(True);

    uint16 where = term.pos_y * term.cols + term.pos_x;
    
    /* Send the high byte */
    outb(0x3D4, 14);
    outb(0x3D5, where >> 8);
    /* Send the low byte */
    outb(0x3D4, 15);
    outb(0x3D5, where);
}
My term_init() function:

Code: Select all

void term_init(boolean clear)
{
    term.cols   = 80;
    term.rows   = 25;
    term.pos_x  = 0;
    term.pos_y  = 0;
    term.tabsz  = 8;
    term.attrib = (0x0 << 4) | (0x7 & 0x0F); /* Grey on black */
    term.buffer = __term_get_video_buffer();
    
    if (clear == True)
        term_clear();
}
I didn't like hardcoding 80 and 25 and what-not, so I did this instead. The clear variable is just so that term_clear() doesn't infinitely recurse.

Re: Cursor not moving

Posted: Sat Feb 20, 2010 1:59 pm
by Owen
bitshifter wrote: Trick:
y shl 4 = y * 16
y shl 6 = y * 64
add them up = y * 80
Look mom, no multiply!

Also keep close eye on variable sizes!
Premature optimization is the root of all evil. And this is beyond premature; it's actually on most processors slower

Re: Cursor not moving

Posted: Sat Feb 20, 2010 3:44 pm
by Synon
Owen wrote:
bitshifter wrote: Trick:
y shl 4 = y * 16
y shl 6 = y * 64
add them up = y * 80
Look mom, no multiply!

Also keep close eye on variable sizes!
Premature optimization is the root of all evil. And this is beyond premature; it's actually on most processors slower
The compiler is usually better at optimizing that sort of thing anyway...

Re: Cursor not moving

Posted: Sun Feb 21, 2010 11:12 am
by Firestryke31
Plus it breaks in the event of a non-80-cell-wide terminal, such as if the OP eventually implements a graphics-mode terminal.

Re: Cursor not moving

Posted: Sun Feb 21, 2010 11:20 am
by Synon
Firestryke31 wrote:Plus it breaks in the event of a non-80-cell-wide terminal, such as if the OP eventually implements a graphics-mode terminal.
Yeah. You'd have to completely change that formula to work with pixels, or in a different video mode.