Programming, for all ages and all languages.
-
claesson92
- Posts: 10
- Joined: Wed Jun 06, 2007 12:26 am
Post
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?
Last edited by
claesson92 on Thu Feb 18, 2010 4:40 pm, edited 1 time in total.
-
Gigasoft
- Member
- Posts: 855
- Joined: Sat Nov 21, 2009 5:11 pm
Post
by Gigasoft »
Well, where's the code for increment_cursor?
-
claesson92
- Posts: 10
- Joined: Wed Jun 06, 2007 12:26 am
Post
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.
-
bitshifter
- Member
- Posts: 50
- Joined: Sun Sep 20, 2009 4:03 pm
Post
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?
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!
-
Synon
- Member
- Posts: 169
- Joined: Sun Sep 06, 2009 3:54 am
- Location: Brighton, United Kingdom
Post
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.
-
Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
-
Contact:
Post
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
-
Synon
- Member
- Posts: 169
- Joined: Sun Sep 06, 2009 3:54 am
- Location: Brighton, United Kingdom
Post
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...
-
Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
-
Contact:
Post
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.
Owner of
Fawkes Software.
Wierd Al wrote:
You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
-
Synon
- Member
- Posts: 169
- Joined: Sun Sep 06, 2009 3:54 am
- Location: Brighton, United Kingdom
Post
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.