My Own printf()

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Ben Hsu

My Own printf()

Post by Ben Hsu »

Hello,
I've written a printf() of my own, but it doesn't
work when i compiled it with my kernel, i can't seem
to find the problem...
this is the file, hope somebody can tell me what's
wrong with it, thanks you!

----------- printf.h ----------
#ifndef __printf_h_
#define __printf_h_

#include <stdarg.h>
#include "string.h" /* includes strcat(char*,char* */
#include "io.h" /* includes puts(void *) */

void printf(const char *format,...)
{
va_list args;

char *buffer;

int ir2,i,null_found=0;
char *pcr3,current=0x20,cr1;

va_start(args,format);

while (*format!=0x00)
{
switch(*format)
{
case '\\':
current='\\';
format++;
switch(*format)
{
case 'n':
*buffer=0x0d;
buffer++;
*buffer=0x0a;
break;
case 'r':
*buffer=0x0d;
buffer++;
*buffer=0x0a;
break;
case 'a':
*buffer=0x07;
break;
case 'b':
buffer--;
buffer--;
break;
case 't':
for (i=1;i<=4;i++)
*(buffer++)=' ';
break;
case '\\':
*buffer='\\';
break;
case 'x':
/* not to implement */
*buffer='-';
break;
default:
*buffer=current;
buffer++;
*buffer=*format;
break;
}
break;

case '%':
current='%';
format++;
switch(*format)
{
case 'b':
/* not to implement */
*buffer='*';
break;
case 'c':
cr1=va_arg(args,char);
*buffer=cr1;
break;
case 'd':
ir2=va_arg(args,int);
break;
case 'f':
/* not to implement */
*buffer='#';
break;
case 's':
pcr3=va_arg(args,char *);
strcat(buffer,pcr3);
break;
case 'x':
/* not to implement */
*buffer='|';
break;
default:
*buffer=current;
buffer++;
*buffer=*format;
break;
}
break;

default:
*buffer=*format;
break;
}
format++;
buffer++;
}

/* now just need to dump [buffer] onto the screen */
puts(buffer);

return;
}
#endif

Thanks,

Ben Hsu
J. Weeks

RE:My Own printf()

Post by J. Weeks »

>On 2001-12-15 18:14:07, Ben Hsu wrote:
>Hello,
> I've written a printf() of my own,

Looks strangely like the version included in GCC :)

>but it doesn't
>work when i compiled it with my kernel, i can't seem
>to find the problem...
>this is the file, hope somebody can tell me what's
>wrong with it, thanks you!

You're calling puts, strcmp, and what-not... have
you implemented those functions as well?

What kind of errors messages do you get?
Those'd be a lot easier to diagnose the code with.

Jeff
Ben Hsu

RE:My Own printf()

Post by Ben Hsu »

>On 2001-12-15 23:40:27, J. Weeks wrote:
>You're calling puts, strcmp, and what-not... have
>you implemented those functions as well?

strcat, puts, and etc. are implemented and they work
pretty good individually...
1.) for puts, it's just ah=0x0e, int 0x10
prototype: void puts(void*);
2.) for strcat, it takes two (char*) and move the
1st pointer to the last char, and begin copying
2nd pointer to the 1st (starting from the end)
prototype: void strcat(char *s1, char *s2);
* it's a little different than the standard string's char* strcat(char *s1,char *2)
3.) for whatever else, (there is actually not)

>What kind of errors messages do you get?
>Those'd be a lot easier to diagnose the code with.

I've used Bochs, and the there is no error shown,
with the exception that after whatever message that
was printed with puts(...) was done, and it's printf(...)
turn, nothing is printed.

It's hard to talk like this, but I've got my CVS
ready on my SourceForge page at:

Project Release:
(uses BOCHS, I think it's already in the .zip file)
http://sourceforge.net/project/showfile ... p_id=24762

CVS:
http://cvs.sourceforge.net/cgi-bin/view ... tos-0.0.1/

And it's a lot easier to look at the whole picture.

I've tried to using my printf() with gcc's putch() to
place everything in the string buffer to the stdout,
but it seems to me that only 0x0d and 0x0a is printed
even when the buffer itself does not contain any 0x0d
or 0x0a.

Thanks.

Ben Hsu
Schol-R-LEA

RE:My printf() function

Post by Schol-R-LEA »

>On 2001-12-16 17:16:17, Ben Hsu wrote:
>>On 2001-12-15 23:40:27, J. Weeks wrote:
>>You're calling puts, strcmp, and what-not... have
>>you implemented those functions as well?
>
>strcat, puts, and etc. are implemented and they work
>pretty good individually...
>1.) for puts, it's just ah=0x0e, int 0x10
> prototype: void puts(void*);

Well, to begin with there is *no* BIOS string
write function; according to
Ralf's List (http://www.ctyme.com/rbrown.htm),
0x10, ah=0x0E prints the *character* stored in
AL to video page BH, and advances the cursor.
You seem to have it confused with int 0x21,
AL=0x09; however, this is a DOS interrupt, and
thus is doubly useless for OS work. Even if you
were in DOS, it *still* wouldn;t work right; that
function expects the string to be delimited with
a '$', while c-strings are NULL-delimited. If you
ran that code in DOS, it would keep printing
garbage past end of your string, until it happens
to find a '$' through sheer chance.

However, if you're in protected mode, this is all
irrelevant; a 16-bit BIOS call won't work at all
unless you drop into either r-mode or v86-mode
first - a *lot* of work just to print a
character. For 32-bit code, there's really no
getting around writing video handling code from
scratch. That's OK, though,as it allows you to
decide how it will work, which may be a lot more
convienent in the long run - and probably more
efficient than the BIOS dreck anyway. Don't
forget to make it reentrant...
Ben Hsu

RE:My printf() function

Post by Ben Hsu »

>Well, to begin with there is *no* BIOS string
>write function; according to
>Ralf's List (http://www.ctyme.com/rbrown.htm),
>0x10, ah=0x0E prints the *character* stored in
>AL to video page BH, and advances the cursor.
>You seem to have it confused with int 0x21,
>AL=0x09; however, this is a DOS interrupt, and

Actually, I have not...it was one of the thing that I
forgot to post here, my assembly codes written with NASM
was a loop with lodsb to al and then print it with int 0x10::ah=0x0e.

btw: Ralf's list had a very interesting function:
ah=0x13
al=writing mode
bh=page #
bl=attribute
cx=string length
dh=y-coordinate
dl=x-coordinate
es:bp=>begin of string
int 0x10

And if you have an PC/AT or above, this will work to print
off that string...(even tho i'm not using it...)

>thus is doubly useless for OS work. Even if you
>were in DOS, it *still* wouldn;t work right; that
>function expects the string to be delimited with
>a '$', while c-strings are NULL-delimited. If you
>ran that code in DOS, it would keep printing
>garbage past end of your string, until it happens
>to find a '$' through sheer chance.
>
>However, if you're in protected mode, this is all
>irrelevant; a 16-bit BIOS call won't work at all
>unless you drop into either r-mode or v86-mode
>first - a *lot* of work just to print a
>character. For 32-bit code, there's really no
>getting around writing video handling code from
>scratch. That's OK, though,as it allows you to
>decide how it will work, which may be a lot more
>convienent in the long run - and probably more
>efficient than the BIOS dreck anyway. Don't
>forget to make it reentrant...

Yeah, i changed to pmode after all, it is super easy to dump stuff
onto the video memory...but I still have the problem that
I can't change where the cursor moves...

I've tried the sample code on MegaTokyo's FAQ, with Bochs,
and what happens is that for every 0x3d4 or 0x3d5 (port #) i write to
there is an error saying that the VGA port doesn't exists...
I've checked my code with the site and it's almost a match...
I'm working on compromising each program the entire screen, or at least
let the few important kernel parts to just begin from 0xb8000 and use some
memory space to begin storing my cursor position...something like that...

Anyways, thanks for the help!

Ben
Post Reply