OSDev.org https://forum.osdev.org/ |
|
[C]Print a character https://forum.osdev.org/viewtopic.php?f=13&t=31109 |
Page 1 of 2 |
Author: | leosa99 [ Thu Dec 22, 2016 11:33 am ] |
Post subject: | [C]Print a character |
Hi ! I'm trying to print a character to the screen with this code : Code: #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: printCharacter(1,3); It does not print the "W" at (1;3) but at an other place. |
Author: | jojo [ Thu Dec 22, 2016 11:55 am ] |
Post subject: | Re: [C]Print a character |
Your math is alllll screwy. Remember that the general rule for placing a value at (x, y) is Code: bitmap_buffer[y * bitmap_width + x] Also, C order of operations generally follows standard PEMDAS. But if you're not sure, use parens. |
Author: | IanSeyler [ Thu Dec 22, 2016 12:03 pm ] |
Post subject: | Re: [C]Print a character |
Can you try the following?: Code: (RAMSCREEN + (2 * (row * 80 + column)))
|
Author: | leosa99 [ Thu Dec 22, 2016 12:29 pm ] |
Post subject: | Re: [C]Print a character |
In fact I already tried, it still doesn't work ... |
Author: | hgoel [ Thu Dec 22, 2016 12:33 pm ] |
Post subject: | Re: [C]Print a character |
Just to make sure, what happens if you call it row and column set to 0? |
Author: | leosa99 [ Thu Dec 22, 2016 12:41 pm ] |
Post subject: | Re: [C]Print a character |
If I call it row and column set to 0 the location of the "W" does not change. |
Author: | hgoel [ Thu Dec 22, 2016 12:53 pm ] |
Post subject: | Re: [C]Print a character |
Does changing the parameters in any way change anything at all? |
Author: | leosa99 [ Thu Dec 22, 2016 1:09 pm ] |
Post subject: | Re: [C]Print a character |
No it does not change anything. |
Author: | Schol-R-LEA [ Thu Dec 22, 2016 3:52 pm ] |
Post subject: | Re: [C]Print a character |
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: 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: #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.) |
Author: | Schol-R-LEA [ Thu Dec 22, 2016 4:00 pm ] |
Post subject: | Re: [C]Print a character |
Having said all that, it occurs to me I forgot to ask: just where is it writing the character to? |
Author: | irvanherz [ Thu Dec 22, 2016 8:25 pm ] |
Post subject: | Re: [C]Print a character |
Does this will put X at the corner of your screen? Code: *((char*)0xB8000) = 'X'; If not, maybe you have initialized wrong GDT base address |
Author: | leosa99 [ Fri Dec 23, 2016 4:05 am ] |
Post subject: | Re: [C]Print a character |
yes it put an X. If i keep the previous code, the W keeps showing at (0;12). |
Author: | iansjack [ Fri Dec 23, 2016 5:39 am ] |
Post subject: | Re: [C]Print a character |
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. |
Author: | matt11235 [ Wed Dec 28, 2016 6:27 am ] |
Post subject: | Re: [C]Print a character |
Schol-R-LEA wrote: Code: typedef struct { uint8_t attrib; unsigned char glyph; } TEXT_FRAME; Shouldn't the character be before the attribute byte in the struct? |
Author: | bauen1 [ Wed Dec 28, 2016 6:42 am ] |
Post subject: | Re: [C]Print a character |
zenzizenzicube wrote: Schol-R-LEA wrote: Code: 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 ? |
Page 1 of 2 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |