My general approach (so far) is to mess with the code as little as possible, but I am not going to make this a strict rule.
I will need to add "protos.h" to the collection of header files in the "h" directory. Then I will need to add an include line for this to each soure file.
The code also has a half hearted effort towards prototypes in the form of statements like this:
extern /*struct pgmapent*/ getpgmap(); /* (addr) */ extern setpgmap(); /* (addr, entry) */The above are from sun3/cpu.map.h I will place true ansi prototype in protos.h and then put these sorts of things under a NOTANSI conditional, which I simply won't define. All of this in the spirit of not deleting anything, both as a nod towards history, but also in case I make a mistake and need to look back at the original code.
And I will need to hand edit each and every C source file changing function definitions from the traditional style to the ANSI style. Sometimes I will make a function return explicitly "void" where it was previously simply defaulting to "int". Also when I notice that a function is used only within the file it is defined in, I will add a "static" declaration.
This is the plan, we will see how it plays out. Some routines are defined in assembly language code and it will be useful to set up ANSI C prototypes for these.
We could "fix" things by liberal use of casting, but this is a case where it would be better (and cleaner) to just do the right thing. Doing the right thing involves looking deeper into the code than the usual "code monkey" type work that a lot of this entails.
A concrete example turns up in sys/commands.c where a pointer in a structure gets used. We see this on line 937:
(*gp->g_vector_cmd)((long)calladx, gp->g_lineptr);Here "gp" points to a structure of global variables. A nice idea to bundle them all together like this in my opinion. The value gets set in reset.c by this code:
extern void vector_default(); gp->g_vector_cmd = vector_default;So, where is vector default define? In sys/commands.c as it turns out. Our first task is to edit commands.c making the function declaration ansi, then we can add a prototype to protos.h. We begin with:
void vector_default(addr, string) char *addr; char *string; {And end up with:
void vector_default ( char *addr, char *string )No special magic there. Then in "h/globram.h" we make this change:
// void (*g_vector_cmd)(); /* Addr of vector cmd */ void (*g_vector_cmd)( char *, char *); /* Addr of vector cmd */I'll note that there are many other function pointers in globram.h that will need attention.
// (*gp->g_vector_cmd)((long)calladx, gp->g_lineptr); (*gp->g_vector_cmd)((char *)calladx, gp->g_lineptr);The bootrom code pretty much randomly uses either int, long, or "char *" to hold addresses. Something that could be cleaned up, but it would be a lot of work, with little reward.
It isn't clear to me why a function pointer is used here at all. The value is never changed. Perhaps the sun programmers had ideas about things that never developed, or just made a habit of doing things in this way if they thought they might have more general urges someday. The address of this pointer is made public in the table generated in romvec.s, so this could be patched by the "user", but I find this a very unlikely scenario. Probably this was used in ways that I cannot imagine.
Tom's Computer Info / tom@mmto.org