Page 1 of 1
Source code problem
Posted: Thu Aug 25, 2005 11:00 pm
by matthias
Hi there,
When I call a function I've written ( con_put(char c); ).. this function should copy a character to a buffer and then it copies the buffer to the videomemory (don't ask why :p I have my reasons for it :p).. but this isn't the case unfortunately. Here is some code:
Code: Select all
#define MAX_CONSOLES 10 // should be OK ;)
typedef struct __console_t
{
char* buffer; // pointer to memory
unsigned short pos; // pointer to current position
int u; // used to chek wheter a console is used
} console_t;
// used to let the manager now which console shoulde be written to.
unsigned int active_con = 0; // std use the kernel console ;)
console_t consoles[MAX_CONSOLES];
char kernel_buffer[4000]; // 80 * 25 * 2 ;)
// following is the init-func.. is called before con_put(char c); func
void con_init()
{
// zero console headers
memset((void*)&consoles, 0, sizeof(console_t) * MAX_CONSOLES);
// create the primary kernel console:
consoles[0].buffer = (char*)&kernel_buffer; // assign buffer
consoles[0].pos = 0; // set our position
consoles[0].u = 1; // used :p
}
void con_put(char c)
{
consoles[active_con].buffer[consoles[active_con].pos] = c; // copy character to buffer
consoles[active_con].pos += 2; // skip over attribute
memcpy((void*)0xb8000, (void*)&consoles[active_con].buffer, 4000); // refresh screen
}
This is the calling code:
Code: Select all
con_put('h');
con_put('e');
con_put('l');
con_put('l');
con_put('o');
But I get something else instead :S The problem is that I get a kinda green color on my screen, only one character. (color: windows98 backgroud color :@) I hope someone can help.
Thanks in advance,
Matthias
Re: Source code problem
Posted: Thu Aug 25, 2005 11:00 pm
by AltCtrlDel
when i face such problem with a code that i am sure it is well written .. i think of stupid causes
try to isolate the various possible causes and test each one separately:
* the mode has not been initialized properly:
try to write directly to the video memory .. no buffers, consoles or such things .. if it works then the mode has been initialized well
* a bug in the memcpy fucntion:
try to use memcpy to write directly into video memory .. if it works then no bugs are there
* a bug in the consoles:
use a single console, don't use a buffer
* a bug that is cannot be determined !!
use an emulator with debugger .. check the video memory to see what is there. BOCHs is good .. there is also VMware Workstation, it doesn't offer a debugger but u can dump the contents of the memory using a simple hack
Re: Source code problem
Posted: Fri Aug 26, 2005 11:00 pm
by carbonBased
For one thing, you should be setting the attribute byte:
Code: Select all
consoles[active_con].buffer[consoles[active_con].pos] = c; // copy character to buffer
consoles[active_con].pos += 2; // skip over attribute
This will set the character, but since the consoles->buffer is assigned an char buffer with no initial value, it'll be tossed into the BSS section. If your loader is doing the right thing, this BSS section will be zerod out, and therefore your attribute byte will be 0; the characters will not show, in this case.
You're memcpy should also be:
Code: Select all
memcpy((void*)0xb8000, (void*)consoles[active_con].buffer, 4000);
--Jeff
Re: Source code problem
Posted: Fri Aug 26, 2005 11:00 pm
by matthias
carbonBased wrote:For one thing, you should be setting the attribute byte:
Code: Select all
consoles[active_con].buffer[consoles[active_con].pos] = c; // copy character to buffer
consoles[active_con].pos += 2; // skip over attribute
This will set the character, but since the consoles->buffer is assigned an char buffer with no initial value, it'll be tossed into the BSS section. If your loader is doing the right thing, this BSS section will be zerod out, and therefore your attribute byte will be 0; the characters will not show, in this case.
--Jeff
--> Problem solved
thanks
I was planning to do the attribute-stuff later on. But now I see that wasn't such a good idea :p
Re: Source code problem
Posted: Sat Aug 27, 2005 11:00 pm
by matthias
Here is the complete source code.. With the problem solved
It works :p
Code: Select all
#include <console.h>
int can_use_mm = 0;
unsigned int active_con = 0; // std use the kernel console ;)
void con_can_use_mm()
{
can_use_mm = 1; // now we can use mm to allocate buffers
}
console_t consoles[MAX_CONSOLES];
char kernel_buffer[4000]; // 80 * 25 * 2 ;)
void con_init()
{
// zero memory buffer
memset((void*)0xb8000, 0, 4000); // 4000 -> 25 lines, 80 columns, 2 bytes per character
// gives: 25 * 80 * 2 = 4000 ;)
// zero console headers
memset((void*)&consoles, 0, sizeof(console_t) * MAX_CONSOLES);
memset((void*)kernel_buffer, 0, 4000); // zero buffer
// create the primary kernel console:
consoles[0].buffer = (char*)&kernel_buffer; // assign buffer
consoles[0].pos = 0; // set our position
consoles[0].u = 1; // used :p
con_set_color(0, 1, 14); // fill buffer with attributes :p
}
void con_switch(int id)
{
if(id > MAX_CONSOLES - 1)
{
con_write(active_con, "Console: error, console id isn't right, NOT switching console\n");
}
else
{
active_con = id;
}
}
int con_create()
{
int i;
for(i = 1; i < (MAX_CONSOLES - 1); i++)
{
if(consoles[i].u == 0)
{
if(!can_use_mm)
{
con_write(active_con, "Console: Cannot assign memory buffer, no support. Not Creating console\n");
return -1;
}
// allocate mem here
con_set_color(i, 0, 7);
consoles[i].pos = 0;
consoles[i].u = 1;
return i;
}
}
con_write(active_con, "Console: Can't create console, all slots taken.\n");
return -1;
}
void con_remove(int id)
{
if(id > MAX_CONSOLES - 1)
{
con_write(active_con, "Console: error, console id isn't right, NOT switching console.\n");
return;
}
if(id == (int)active_con)
{
con_write(active_con, "Console: error, cannot remove current console, switch to other console first.\n");
return;
}
consoles[id].u = 0;
consoles[id].pos = 0;
// free memory
}
void con_put(char c)
{
consoles[active_con].buffer[consoles[active_con].pos] = c;
consoles[active_con].pos += 2; // skip over attribute
memcpy((void*)0xb8000, (void*)consoles[active_con].buffer, 4000); // refresh screen
}
char con_get(int column, int row)
{
return (consoles[active_con].buffer[(row * 80) + column]);
}
void con_write_buf(int id, char* s, size_t length)
{
// dummy for now
}
void con_write(int id, char* s)
{
// dummy for now
}
void con_set_color(int id, int back, int text)
{
if(id > MAX_CONSOLES - 1)
{
con_write(active_con, "Console: error, console id isn't right, NOT switching console.\n");
return;
}
char a = (text + (back << 4) + (0 << 7)); // pre-calculate.. speed optimization :p
int i;
for(i = 1; i < 4000; i += 2) // only copy attribute bytes ;)
{
consoles[id].buffer[i] = a;
}
}
Matthias