Page 1 of 1

Problem with my rewritten printf function

Posted: Sun Mar 30, 2008 1:58 am
by White-spirit
Hello,

I have a little problem with my printf function, it prints only Genuin instead of printing GenuineIntel on the screen .

But if I use print ( without stdarg ), it works properly .

What's wrong please ?

Thanks .

PS : Here's my code :

Code: Select all

#include <stdarg.h>

void clrscr ();
void scroll ();
void print (const char*);
void printf (int, ...);
extern void get_vendor (char*);

unsigned int x=0;
unsigned int y=0;

int kernel_main(void)
{
	char buffer[13];
	clrscr();
	get_vendor(buffer);
	printf(3,"\n>CPU Vendor : ",buffer,"\n");
	while(1);
	return(0);
}

void clrscr (){
	int i;
	unsigned char* screen = (unsigned char *) 0xB8000;
	for (i=0;i<80*25;i++){
		*screen++=0x0;
		*screen++=0x07;
	}
}

void scroll()
{
    int i;
	unsigned char *screen = (unsigned char*) 0xB8000;
    for (i = 0*80; i < 24*80; i++)
    {
        screen[i] = screen[i+160];
    }
    for (i = 24*80; i < 25*80; i++)
    {
        screen[i] = 0;
    }
    y = 24;
}

void printf( int n, ... ){
	va_list ap;
	int i=0;
	va_start(ap, n);
	for( ; n>0 ; n--) print(va_arg(ap, const char* ));
	va_end(ap);
}
void print( const char* chaine )
{
	int i;
	unsigned char* screen = (unsigned char*) (0xB8000+y*160+x*2);
	while ( *chaine ){
		if (*chaine == 0xA ){ // LF : 0x0A
			x=0;
			y++;
			screen=(unsigned char*) (0xB8000+y*160);
			chaine++;
		} else {
			*(screen++)=*(chaine++);
			*(screen++)=0x07;
			x++;
		}
		if (x>=79){
			x=0;
			y++;
		}
		if (y>=24){
			scroll();
			y=1;
		}
	}
}

Posted: Sun Mar 30, 2008 2:14 am
by White-spirit
Arf it's only the kernel's size that is too big ... so it works .

How to do something like printf("Lorem ipsum","\n") instead of printf(2,"Lorem ipsum","\n"); ?

Thanks and sorry for the little mistake :s

Posted: Sun Mar 30, 2008 8:34 am
by Krox
In C thats not possible, cause the number of arguments is unknown to the called function. Im not sure weather C++ supports variadic templates. It would be possible than (like it is possible in D).

But anyway, thats not the way, the function printf normally works. A normal printf-call is somethig like

Code: Select all

printf("name: %s, age: %d", "arthur", 42);
which prints "name: arthur, age: 42". So the first parameter is the "format-string", and every "%X" is substituted by a following value. The letter aber the % is indicating the type of that value. Integer, String, Floating-Point... there are more. For a nice (and I think complete) implementation you should google for the Linux Kernel Version 0.0.1.

edit: well, little bit offtopic, but I like to mention the really good templace- faculties of D: There you can easily write a Output function (I have done so) which receives any number of arguments of any types and it formats it the right way. Actually thats the same as the Pascal builtin output function, and its more beautiful than printf or C++ Streams I think :)