[C]Print a character

Programming, for all ages and all languages.
leosa99
Posts: 21
Joined: Tue Aug 30, 2016 9:34 am
Libera.chat IRC: leosa99

[C]Print a character

Post by leosa99 »

Hi !
I'm trying to print a character to the screen with this code :

Code: Select all

#define RAMSCREEN 0xB8000 // Video address.

void printCharacter(char row, char column) // It print a character at the selected location.
{
unsigned char *res_location;
res_location = (unsigned char*)(RAMSCREEN + 2 * (row * 80 + column));
res_location[0]='W';
res_location[1]=0xd;
}
I call it with :

Code: Select all

printCharacter(1,3);
It does not print the "W" at (1;3) but at an other place.
User avatar
jojo
Member
Member
Posts: 138
Joined: Mon Apr 18, 2016 9:50 am
Libera.chat IRC: jojo
Location: New York New York

Re: [C]Print a character

Post by jojo »

Your math is alllll screwy. Remember that the general rule for placing a value at (x, y) is

Code: Select all

bitmap_buffer[y * bitmap_width + x]
Also, C order of operations generally follows standard PEMDAS. But if you're not sure, use parens.
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: [C]Print a character

Post by IanSeyler »

Can you try the following?:

Code: Select all

(RAMSCREEN + (2 * (row * 80 + column)))
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
leosa99
Posts: 21
Joined: Tue Aug 30, 2016 9:34 am
Libera.chat IRC: leosa99

Re: [C]Print a character

Post by leosa99 »

In fact I already tried, it still doesn't work ...
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

Re: [C]Print a character

Post by hgoel »

Just to make sure, what happens if you call it row and column set to 0?
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
leosa99
Posts: 21
Joined: Tue Aug 30, 2016 9:34 am
Libera.chat IRC: leosa99

Re: [C]Print a character

Post by leosa99 »

If I call it row and column set to 0 the location of the "W" does not change.
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

Re: [C]Print a character

Post by hgoel »

Does changing the parameters in any way change anything at all?
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
leosa99
Posts: 21
Joined: Tue Aug 30, 2016 9:34 am
Libera.chat IRC: leosa99

Re: [C]Print a character

Post by leosa99 »

No it does not change anything.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [C]Print a character

Post by Schol-R-LEA »

Might I suggest that rather than trying to muck about with a pointer, you treat the buffer as two-dimensional array of a struct containing the two bytes?

Code: Select all

typedef struct {
    uint8_t attrib;
    unsigned char glyph;
} TEXT_FRAME;

TEXT_FRAME *text_buffer = (TEXT_FRAME *) 0xb8000;

#define COLUMN_OFFSET 80

// ...

    text_buffer[(rows * COLUMN_OFFSET) + columns].glyph = 'W';
    text_buffer[(rows * COLUMN_OFFSET) + columns].attrib = 0xd;
Actually, given that there are several text modes, and you also need to bounds-check the text buffer (among other things), I would go with something more like:

Code: Select all

#define DEFAULT_TEXT_MODE 0x03
#define DEFAULT_CODE_PAGE 437   // or set this to a page suited to your native language 

struct {
    uint8_t total_rows, total_columns;
} TEXT_MODES[255] = {
    // populate this with a lookup table for the modes by mode #
};

typedef struct {
    uint16_t row, column;
} TEXT_CURSOR;

typedef struct {
    TEXT_MODE mode;
     uint16_t code_page;
    TEXT_CURSOR cursor;   
    TEXT_BUFFER buffer;
} TEXT_PAGE;

const TEXT_BUFFER buffers[] = {
    (TEXT_FRAME *) 0xB8000,
    // .. I can't seem to find the rest of the entry points for the other three 
    // text pages ... anyone?
};  

TEXT_PAGE pages[4];

void kinit_console()
{ 
    int i;

    for (i = 0; i < 4; i++) 
    {
        pages[i].mode = DEFAULT_TEXT_MODE;
        pages[i].code_page = DEFAULT_CODE_PAGE;
        pages[i].cursor.row = 0;
        pages[i].cursor.column = 0;
        pages[i].buffer = buffers[i];
}

bool k_gotoxy(TEXT_BUFFER *page, uint8_t row, uint8_t col, bool reset_hw_cursor)
{
    if (row >= page ->text_mode.total_rows || col >= page ->text_mode.total_columns)
    {
        return false;
    }

    page ->cursor.row = row;
    page ->cursor.column = col;
    if (reset_hw_cursor)
    {
        set_vga_cursor(row, col);
    }

    return true;
}

void kputchar(TEXT_BUFFER *page, unsigned char ch)
{
    int *x = &page ->cursor.columns;
    int *y = &page ->cursor.rows;
    int x_offset = page ->text_mode.total_columns;
    int y_offset = page ->text_mode.total_rows;
    FRAME_BUFFER *buffer = page ->buffer;

    if (x <= x_offset)
    {
        x = 0;
        y++;
    }
    else
    {
        x++;
    }

    if (y <= y_offset)
    {
        // handle scrolling or clearing page as you choose
    }
    
    buffer[(y * x_offset) + x].glyph = ch;

    set_vga_cursor(x, y);
}
(Not tested code, just use this as a guide.)
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: [C]Print a character

Post by Schol-R-LEA »

Having said all that, it occurs to me I forgot to ask: just where is it writing the character to?
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
irvanherz
Member
Member
Posts: 27
Joined: Mon Sep 19, 2016 5:34 am

Re: [C]Print a character

Post by irvanherz »

Does this will put X at the corner of your screen?

Code: Select all

*((char*)0xB8000) = 'X';
If not, maybe you have initialized wrong GDT base address
leosa99
Posts: 21
Joined: Tue Aug 30, 2016 9:34 am
Libera.chat IRC: leosa99

Re: [C]Print a character

Post by leosa99 »

yes it put an X.
If i keep the previous code, the W keeps showing at (0;12).
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: [C]Print a character

Post by iansjack »

You should

1. Inspect the generated code.

2. Then single-step through it in a debugger.

It should then be fairly obvious what is going wrong.
User avatar
matt11235
Member
Member
Posts: 286
Joined: Tue Aug 02, 2016 1:52 pm
Location: East Riding of Yorkshire, UK

Re: [C]Print a character

Post by matt11235 »

Schol-R-LEA wrote:

Code: Select all

typedef struct {
    uint8_t attrib;
    unsigned char glyph;
} TEXT_FRAME;
Shouldn't the character be before the attribute byte in the struct?
com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
Compiler Development Forum
User avatar
bauen1
Member
Member
Posts: 29
Joined: Sun Dec 11, 2016 3:31 am
Libera.chat IRC: bauen1
Location: In your computer
Contact:

Re: [C]Print a character

Post by bauen1 »

zenzizenzicube wrote:
Schol-R-LEA wrote:

Code: Select all

typedef struct {
    uint8_t attrib;
    unsigned char glyph;
} TEXT_FRAME;
Shouldn't the character be before the attribute byte in the struct?
Correct me if i'm wrong but should this have the packed attribute ?
myunix (version 3) (name suggestions are welcome!)
GPG Key fingerprint: 5ED6 D826 ACD4 3F8E D9D4 FBB2 FF0A AF5E 0812 BA9C
Post Reply