IMO, getting that to work correctly was a total PIA. The affected part of
the code is not very flexible IMO.
The original newfunc() counted the args, then called getarg() as needed to
save the pertinent info about the args.
To rework it for ANSI C, basically, I moved the getarg() code up and
eliminated the second loop. So, it was counting and storing arg info in one
loop. The parsing was correct, but one value of the arg info was now
incorrect. The problem only appeared if there were two or more parameters
in a function call...
The affected value was argstk which eventually was passed to addloc()'s
fourth arg "value" via getarg() via newfunc(). Unfortunately, this value is
dependent on the total number of parameters. I had just changed the parsing
ordering so the total number of arguments wasn't known in advance. The
"new" argstk values were incorrect.
I scrapped that idea and attempted to keep the original parsing method, but
that would require the parser to back up an entire line of the text stream
and reparse it... One pass was needed to parse to get the arg count and
another pass to get the args. AAAH! So, that wasn't looking too good to me
either. Because of that, I decided that maybe forcing my way forward with
the first attempt was a better idea. So, I went back to the first attempt
and made that work.
At least I learned that separating the args and their declarations, like K&R
C, makes parsing them easier. You can count them first, then parse their
declarations, and adjust their ordering or storage as needed. You don't
need to do all at once like ANSI C.
With the first attempt, getarg() and addloc() had already been called with
the wrong values for argstk. To fix it, I needed to back up the locals
stack and insert the correct values into the local's data after the fact.
Yuck, horrid, but not too horrid... Fortunately, the local's data was
simply stored flatly somewhere between startloc and endloc by incrementing
locptr by symsize.
I think I'm keeping all additional modifications to SmallC really really
simple from now on. Everytime I attempt to do something that should be
"easy" I end up breaking everything in sight. I'm guessing my original
successes were with modifying stuff that wasn't too brittle or complex.
Next, I'm hoping to add a single-level, i.e., no nesting, #ifdef and #endif
preprocessor functionality next. The idea is to use findmac() to find the
#ifdef's symbol and use keepch() to insert ANSI C comment tokens to remove
inactive code the same way as it removes an ANSI C comment.
Rod Pemberton
"moved the getarg() code" in newfunc() "up and"
Also, getarg() had the while loop removed and adjusted slightly for ANSI C
syntax. The argstk increment and decrement lines in both routines were
relocated to work for the new logic.
RP
> At least I learned that separating the args and their declarations, like K&R
> C, makes parsing them easier. You can count them first, then parse their
> declarations, and adjust their ordering or storage as needed. You don't
> need to do all at once like ANSI C.
>
> With the first attempt, getarg() and addloc() had already been called with
> the wrong values for argstk. To fix it, I needed to back up the locals
> stack and insert the correct values into the local's data after the fact.
> Yuck, horrid, but not too horrid... Fortunately, the local's data was
> simply stored flatly somewhere between startloc and endloc by incrementing
> locptr by symsize.
>
> I think I'm keeping all additional modifications to SmallC really really
> simple from now on. Everytime I attempt to do something that should be
> "easy" I end up breaking everything in sight. I'm guessing my original
> successes were with modifying stuff that wasn't too brittle or complex.
>
> Next, I'm hoping to add a single-level, i.e., no nesting, #ifdef and #endif
> preprocessor functionality next. The idea is to use findmac() to find the
> #ifdef's symbol and use keepch() to insert ANSI C comment tokens to remove
> inactive code the same way as it removes an ANSI C comment.
>
Code on!
I haven't had the chance to revisit small-c in quite a while. I need
to rework c5lib.c, I declared the file structures and buffers as
locals (they end up on the stack) whereas they should be as static
data, you might want to take a closer look at that. (I think there is
an issue because of the recursive nature of statement parser in the
workings of an #include statement, i.e. a new stack frame. This may
also pertain to your preprocessor workings).
Steve
> Rod Pemberton
BTW, that's just the parameters. I haven't looked into the function
returns.
...
...
Ok, now that you've thought about that for a second or two, yeah, SmallC
could use a "void" type for return's without a value. Yes? IIRC, ANSI C
doesn't support implicit int's, so the return type must be specified, e.g.,
int or void. AIUI, SmallC effectively implements void but has no keyword or
type for it. Or, without an explicit void type, I guess the code may be all
converted to returning int's even if unused. That works, I think... I'm
also pretty sure that placing an "int" in front of a function is going to
really mess with the parsing. Except for maybe casts and structs, I'm
thinking I could eventually convert SmallC to ANSI. The structs project
using the Z80 SmallC code is on-hold, probably forever. But, even so, that
could be enough to allow a bootstrap via GCC without c5libc and only a
handful of warnings, perhaps.
> That could be better managed by rewriting the one pass parser into a
> multi-pass design, I think.
>
I've got a few other personal C and/or C-like parsers/compilers in the
works. One of them looks like it'll be really useful for C-to-C
translations or rewriting. E.g., converting loops to while(1), unrolling C
assignments, reducing complex code, etc. I haven't done any work on it in a
while do to my numerous other projects.
I've searched for public projects that do C-to-C translations. I've only
found three:
C2C from the CILK project
CIL by George Necula and others
LLVM by University of Illinois
C2C only parses C, syntax checks it, then emits the exact same C code...
Unfortunately, there are no optimizations or translations, AFAICT.
CIL is C Intermediate Language by Necula et. al. This should not be
confused with CIL Common Intermediate Language by MS. Necula's CIL performs
a number of C-to-C translations as well as reduce GCC and MS C and many of
their extensions. (Nice!) When I looked at it, it's parser was written in
another language and it required various other software I didn't want to
install. It'll probably turn out to be the best solution.
LLVM is poorly named: Low Level Virtual Machine. It's actually a set of C
compiler tools. LLVM's backend can emit C code, but IMO it's actually too
low of a level! It emit's branches and loops, etc., as goto's, not while(1)
or for(;;) etc. The emitted code is ready to be compiled or directly
converted to assembly, but not useful if you need to maintain or modify it
as C code.
As for GCC, it'd be really nice if GCC emitted a low-level subset of C, but,
AFAICT, there is no such feature for GCC. The closest seems to be GCC -E (I
think...) to preprocess the code, but that emits a bunch of junk also. Such
a feature would allow C programs to be simplified so they could be compiled
by simpler C compilers, such as SmallC. I first started considering the
idea a number of years ago after seeing Lutz Hamel's C subset compiler WCC
from DECUS. Necula's CIL, which reduces GCC C and MSVC C and many of their
extensions to simplified standard C, reinforced the idea that this was
useful and doable.
I may once again look into porting Fabrice Bellard's TCC C compiler. It's
possible that it may be useful for C-to-C translation. AIUI, it converts C
to a bunch of simple functions in C that are effectively it's assembly
language. I.e., it's doing C-to-C, albeit probably in an irregular way. As
long as the simple C compiler can compile functions and include a file with
a set of them, it's not pretty C code but should work...
Rod Pemberton
Um yes, on the road to ansi. Decisions need to be made on
implementation. Is 'void' a clue to the compiler not to generate code
to return a value, or, return a null. This K&R passage can be
imagined a couple of ways:
"
A function need not return a value; a 'return' statement with no
expression causes control, but no useful value, to be returned to
thecaller, as does "falling off the end" of a function by reaching the
terminating right brace.
"
> doesn't support implicit int's, so the return type must be specified, e.g.,
Um wasn't early ansi functions typed as int by default if
unspecified .. well maybe that was the case for only the very early
ones which handled both ansi and K&R.
> int or void. AIUI, SmallC effectively implements void but has no keyword or
> type for it. Or, without an explicit void type, I guess the code may be all
> converted to returning int's even if unused. That works, I think... I'm
IIRC, SmallC returns the int or char type of the 'return' expression,
and whatever is in the primary register if no expression.
> also pretty sure that placing an "int" in front of a function is going to
> really mess with the parsing. Except for maybe casts and structs, I'm
For small-c yes, the parser wasn't made to handle that.
> thinking I could eventually convert SmallC to ANSI. The structs project
> using the Z80 SmallC code is on-hold, probably forever. But, even so, that
> could be enough to allow a bootstrap via GCC without c5libc and only a
> handful of warnings, perhaps.
>
I'm not clear on what the endgame is of a bootstrap via GCC, is it to
get to 32bit code generation?
I think you recall I used Mix Software's PowerC to boot strap small-c
before I had built c5lib.c, effectively using PowerC's I/O library,
and its ability to handle K&R. So maybe it is that you want GCC's I/O
library.
> > That could be better managed by rewriting the one pass parser into a
> > multi-pass design, I think.
>
> I've got a few other personal C and/or C-like parsers/compilers in the
> works. One of them looks like it'll be really useful for C-to-C
> translations or rewriting. E.g., converting loops to while(1), unrolling C
> assignments, reducing complex code, etc. I haven't done any work on it in a
> while do to my numerous other projects.
>
> I've searched for public projects that do C-to-C translations. I've only
> found three:
>
> C2C from the CILK project
> CIL by George Necula and others
> LLVM by University of Illinois
>
Have you run across ansi2knr.exe? I don't think I've used it ever, it
seems to be part of the GNU utilities.
/* Copyright (C) 1989, 1997, 1998, 1999 Aladdin Enterprises. All
rights reserved. */
/*$Id: ansi2knr.c,v 1.14 1999/04/13 14:44:33 meyering Exp $*/
/* Convert ANSI C function definitions to K&R ("traditional C") syntax
*/
I don't have a good link for it, maybe you have it already.
Interesting info.
Steve
> Rod Pemberton
Since the basic correct functionality is there, the syntax of "int" "char"
"void" or whatever could just be discarded... I.e., it fakes it. There'd
be no actual check that if the function is declared as returning an int or
char that it is actually returning an int or char. That's a possible
"solution" - just ignore the syntax. It could then compile itself and be
compiled as ANSI C by other compilers.
> I'm not clear on what the endgame is of a bootstrap via GCC, is it to
> get to 32bit code generation?
>
> I think you recall I used Mix Software's PowerC to boot strap small-c
> before I had built c5lib.c, effectively using PowerC's I/O library,
> and its ability to handle K&R. So maybe it is that you want GCC's I/O
> library.
Maybe I'm going in circles again... ;) I was thinking it'd be a little
easier to bootstrap or maintain if it was ANSI C.
> > I've searched for public projects that do C-to-C translations. I've only
> > found three:
>
> > C2C from the CILK project
> > CIL by George Necula and others
> > LLVM by University of Illinois
> >
>
> Have you run across ansi2knr.exe? I don't think I've used it ever, it
> seems to be part of the GNU utilities.
>
> I don't have a good link for it, maybe you have it already.
>
No, I haven't. GNU? Let me search for it. Yes, ansi2knr.c is available 28
times with various GNU projects that come with DJGPP. But, it comes in four
different file sizes and ten different dates... It's not compiled as a part
of DJGPP.
Is there one going the other way? It seems there is a perl script called
knr2ansi.pl. It's part of CXREF. I think it just produces the proto types
and places them in separate files. It doesn't fix the code, AFAICT.
Rod Pemberton
Sure, that would work until other types like float are brought into
the mix.
> > I'm not clear on what the endgame is of a bootstrap via GCC, is it to
> > get to 32bit code generation?
>
> > I think you recall I used Mix Software's PowerC to boot strap small-c
> > before I had built c5lib.c, effectively using PowerC's I/O library,
> > and its ability to handle K&R. So maybe it is that you want GCC's I/O
> > library.
>
> Maybe I'm going in circles again... ;) I was thinking it'd be a little
> easier to bootstrap or maintain if it was ANSI C.
>
I'd guess that that is true[1]. Small-c is vectored from a particular
point in history. If your goal is a lightweight ANSI C written in
ANSI C, and that is a goal as worthy as any, then perhaps it is time
for a small-ansi-c using ansi features from the outset. If the goal
is to walk the 'crop circle' that is small-c to arrive at an ansi-c,
then keep on. I think that is worthy goal too, more instructive in
the effort and the means.
[1] There is some caveat around the memory {calloc, malloc,etc.}
functions and goto's {setjmp, longjmp} and {brk,sbrk} implementations
(or the bootstrapping of them).
> > > I've searched for public projects that do C-to-C translations. I've only
> > > found three:
>
> > > C2C from the CILK project
> > > CIL by George Necula and others
> > > LLVM by University of Illinois
>
> > Have you run across ansi2knr.exe? I don't think I've used it ever, it
> > seems to be part of the GNU utilities.
>
> > I don't have a good link for it, maybe you have it already.
>
> No, I haven't. GNU? Let me search for it. Yes, ansi2knr.c is available 28
> times with various GNU projects that come with DJGPP. But, it comes in four
> different file sizes and ten different dates... It's not compiled as a part
> of DJGPP.
>
> Is there one going the other way? It seems there is a perl script called
> knr2ansi.pl. It's part of CXREF. I think it just produces the proto types
> and places them in separate files. It doesn't fix the code, AFAICT.
>
Have you thought about a LEX effort?
Steve
> Rod Pemberton
No. Although, if starting from scratch, it'd probably only require
flex/lex, not needing bison/yacc. I'd rather have a C only solution and
preferably Public Domain. AWK scripts would probably work too. But, I'd
rather have C code than scripts and grammars.
I did find C lex/yacc grammars that I updated to ANSI C and tweaked for
flex/bison. But, I was doing some other work with them. And, I made many
changes. I also attempted to integrate C preprocessing... That was a *BAD*
idea. The C preprocessor is it's own nightmare, and I knew that. A bunch
of those changes would need to be backed out or cleaned up prior to
reworking for C-to-C. Along the way, I ran into a few serious complications
of using flex and bison together for C lexing and parsing. So, I'm not that
fond of flex/bison (or lex/yacc) right now. Maybe when my mood towards
flex/bison changes, I'll revisit it.
Rod Pemberton
Have you collected information about 'lint'? Do you think it would
help with C-to-C? It originated with PCC on unix, but I don't have
any source code of it. I vaguely remember a pclint, but I think it
was a commercial product.
A short article..
http://www.icpug.org.uk/national/archives/020113ar.htm
overview..
http://www.pdc.kth.se/training/Tutor/Basics/lint/index-frame.html
or..
http://www.opengroup.org/onlinepubs/007908799/xcu/lint.html
or..
http://en.wikipedia.org/wiki/Lint_(software)
Steve
I have no idea...
AFAIK, I've never used a system that had it. I don't believe the Unix,
Linux, or *BSD systems I've used had it. I also pretty sure the non-*nix
didn't have it. It possible a system(s) might've had it. It's not
something I would've looked for...
I thought it was an error checker. I've only seen sample output. IMO, the
sample output was debatable as to usefulness. Most compilers can emit
warning and error messages.
> It originated with PCC on unix, but I don't have
> any source code of it.
>
That seems to be one of the problems with lint. Where's the source?
I didn't know it was PCC based. So, it has a compiler, or at least the
lexer and parser, at it's core. It would likely still need reworking to do
the transforms and a backend to emit C. I.e., I'm guessing that it doesn't
emit C, but emits error messages mixed with the original C code. Although,
it should be more advanced than CILK's C2C. Until recently, the PCC
compiler was abandoned in favor of GCC. So, I'm wondering whether lint has
been maintained.
> I vaguely remember a pclint, but I think it
> was a commercial product.
>
ISTM that all versions are commercial. I just checked Wikipedia. It
mentions Splint. It's open source as GPL'd. It was being maintained.
Except for that one, I don't recall locating a lint that has source and is
non-commercial.
I did download the prior version of Splint: 3.1.1. It seems I was looking
at it and some other programs a few years ago for "error correction".
Splint does have grammars. I didn't look to see if they were the main
parser/lexer, or something secondary. I'm assuming for now they are
primary.
Rod Pemberton
FYI, a DDJ article says Pete Gray wrote a 20 program test suite for SmallC.
"Porting Small-C" by Pete Gray
http://www.drdobbs.com/web-development/184405595
http://petegray.newmicros.com/
I didn't see it. I probably overlooked it. Or, maybe it's available upon
asking.
Rod Pemberton
Yes, I can only guess that memory resources were limited so strong
syntax checking was put in lint instead of cc proper.
> > It originated with PCC on unix, but I don't have
> > any source code of it.
>
> That seems to be one of the problems with lint. Where's the source?
>
Good question, maybe it is lost.
> I didn't know it was PCC based. So, it has a compiler, or at least the
> lexer and parser, at it's core. It would likely still need reworking to do
Yes, my understanding that the backend was absent & just the
diagnostics & msgs were expanded, that its base was the same compiler.
Steve
Yes, it's there, there's a drop down menu to the right of the NMI
banner..
"
/*
** Small-C Compiler -- Part 1 -- Top End.
** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
** All rights reserved.
*/
#include <stdio.h>
#include "notice.h"
#include "cc.h"
"
So, a Hendrix version for ..
Small C cross-compiler and Assembler for the Motorola DSP56800
Microcontroller Family
"
The Basics
==========
scdsp.exe - Small C cross-compiler for the DSP56800
sa568.exe - Small Assembler for the DSP56800
scdefs.h - header file required for Small C programs
vec*.asm - file required for sa568, contains dummy vectors and DSP
init code.
flash_over_jtag.exe - Motorola's free JTAG flash loader
flash*.cfg - Flash Loader configuration files for the DSP56800 chips
"
Nothing about a test suite that I could find but there are a number of
support programs and their sources.
Steve
Adding just one return type was *much* easier than fixing the parameters.
I added just an "int" function return type to the parsing. I figured that
most return an int and most of the rest didn't return anything i.e., an
unimplemented "void" type. So for them, returning an int is irrelevant. If
they returned a char, they could be converted to int. That'd just leave
int* and char*, if any...
Adding an "int" function return type required a few lines to "int" section
of parse(). I didn't fix SmallC to actually use the fact the return type is
an int for anything. I needed to look ahead in parse(), so I could
distinguish between a function and a declaration. I saved ltpr. Checked
for "*", e.g., in case there is an pointer declaration, "int *". Then, I
called symname() to move past the name of the variable, array, function,
etc. That provides the lookahead. Next, I checked for a "(" and
assumed it's a procedure, if "(" is there... If "(" is found, I restore
lptr and call newfunc(). Otherwise, I restore ltpr and call decglb() and
ns(), like the original code there. I left in the original "implicit int"
newfunc() call at the end of parse(). That made converting the code easier
by allowing SmallC to be changed incrementally.
After adding "int" return type to nearly every function in SmallC (and
c5libc), I also added "return 0;" for SmallC (not c5libc) *where needed* to
eliminate GCC warnings. This is compatible with SmallC syntax also.
outbyte() was the only function that needed a slight change, in the version
I'm working on, so that there wasn't a char-int mismatch.
So, with int return types, returns, && and || added, the main program
compiles by GCC with only two classes of warnings: various cast warnings,
and implicit function declaration warnings, and still compiles with
(enhanced) SmallC. That's not too bad, IMO. Reordering the functions
should remove almost all of the out-of-order declaration warnings. There
might be a couple remaining due to cross-linked function calls. I haven't
looked into how to move main() to the end yet, and still keep things
compatible with your c5lib. I know main() must be at the start currently
because there is no jump in the assembly start. I don't have plans to add
casts to SmallC, but I may rework the code so that the casts warnings are
all of one type of warning instead of the current 5 warnings. I should be
able to get it down to two: integer-pointer and pointer-integer, by
reworking the code for the other three. Those casts may be easier for
someone to fix, if they decide to compile with GCC.
I've not tried my idea for a simple #if 0 - #endif processing yet. If
implemented, it can be used with a #define to hide GCC's casts when compiled
for SmallC. Then, the code will be 99% ANSI C.
I did notice that parse() parses pre-processor commands _after_ other C
stuff... Odd. I'll probably reorder that...
Structs are the thing still on my mind as *really* being needed... I did
attempt to cut-n-paste from another version a while ago. Much drops right
in, but some of it was too different, i.e., I've have to code something to
fit... I also need to get the prolog/epilog, BP/SP stackframes working for
mine. Then dual-mode 16-bit/32-bit, which should be easy. I'm also toying
with the idea of converting your lib to GCC... It was 32-bit before I
converted to your lib. Once structs are added, it should be useful! The
rest is just "nice" trivialities.
Rod Pemberton
Hey that's great!
> should remove almost all of the out-of-order declaration warnings. There
> might be a couple remaining due to cross-linked function calls. I haven't
> looked into how to move main() to the end yet, and still keep things
> compatible with your c5lib. I know main() must be at the start currently
The only issue with c5lib is its: initfcb(); /** in this file **/ -
must be called to setup the file structures before file I/O is done.
It's mainmain() is first in c5lib expecting a user program to #include
it first in his program in order to make use of it. So mainmain() is
actually unused in Small-c because it is #include last in the small-c
code, and to small-c main(), has been added, the call to initfcb().
I don't have an understanding of your target with GCC..?.. maybe just
to see if GCC would compile it?
> because there is no jump in the assembly start. I don't have plans to add
> casts to SmallC, but I may rework the code so that the casts warnings are
> all of one type of warning instead of the current 5 warnings. I should be
> able to get it down to two: integer-pointer and pointer-integer, by
> reworking the code for the other three. Those casts may be easier for
> someone to fix, if they decide to compile with GCC.
>
> I've not tried my idea for a simple #if 0 - #endif processing yet. If
> implemented, it can be used with a #define to hide GCC's casts when compiled
> for SmallC. Then, the code will be 99% ANSI C.
>
> I did notice that parse() parses pre-processor commands _after_ other C
> stuff... Odd. I'll probably reorder that...
>
I guess, but those 'else if's are the poor man's switch cases, only
one is activated per while loop, with newfunc() being the default
case.
I haven't hardly looked at small-c in quite a while, too busy with
other little projects. I ran across some old TCJ issues with a four
part series on Threaded Code, really forth, that you may be interested
in knowing about..
http://kiblerelect.com/tcj/archive/
tcj_09, tcj_10, tcj_11, tcj_12.pdf's
Steve
1) Syntax wise, ANSI C is a better solution, than K&R. It'll be around for
a while longer. It's possible the code will need to be compiled or
bootstrapped in the future, e.g., via GCC likely. SmallC doesn't usually
come with a library, like c5lib, that you provided.
2) c5lib works in a Win98 dosbox for me. But, I've not got it to work for
real-mode MS-DOS, at least the version I've got. So, anything compiled with
SmallC needs to include c5lib currently and run in a dosbox. I.e., no
real-mode DOS applications. I compile mostly with DJGPP because I can run
the applications in DOS or a Win98 dosbox, whichever I need. Win98 has
better memory management etc., so the applications typically run faster.
IIRC, you were looking at an Int 0x21 version. I may look to see what it
takes to port yours to GCC and/or Int 0x21. We'll see what happens...
3) I was having some issues with the epilog/prolog and/or ESP/EBP
strackframe code. I didn't find the error. I don't know if it is in SmallC
or in c5lib. If I can bootstrap without c5lib by using other code, then I
know where the problem is.
4) Psychological irrationalities that must be satisfied... ? ;-)
Sometimes, the problem is all there is...
> > I did notice that parse() parses pre-processor commands _after_ other C
> > stuff... Odd. I'll probably reorder that...
> >
>
> I guess, but those 'else if's are the poor man's switch cases, only
> one is activated per while loop, with newfunc() being the default
> case.
>
I was thinking about precedence, i.e., pre-processor processing is normally,
or in theory, completed prior to, or takes precedence over other parsing.
However, the '#' syntax probably nullifies any real concerns there. It
shouldn't match other syntax... Although, I'm not big on "it shouldn't".
FYI, IIRC, ANSI C allows whitespace between # and pre-processor command. I
don't think it's a great idea to extend pre-processor further, it should be
separate, IMO. Although, I would like #if <value> and #endif, maybe #ifdef,
since SmallC is "self-contained".
> I haven't hardly looked at small-c in quite a while, too busy
> with other little projects.
>
Yeah, anything cool?
> I ran across some old TCJ issues with a four part series
> on Threaded Code, really forth, that you may be interested
> in knowing about..
>
Thanks. I'll definately take a look.
Yeah, I'm still trying to get some of the C code removed from the backend of
my Forth interpreter... More Forth, less C - although it'll still be a C
program. I've let that problem sit and age for a while. :-) I was trying
to do it incrementally, but doing so meant I had to keep creating both C and
Forth variables to keep everything sync'd between the two. Ugly. Real
ugly. Not recommended ever. Basically, they are two separate environments
that must work together, at the moment. "I've got to 'wash' that C right
out of my Forth! Ahem..." I'm waiting until a spot of brilliance shines
upon the project, or I get up the courage to just go all out and fix the
remaining issues by brute force.
Rod Pemberton
Yeah, ISTM there are bunch of articles on CP/M, Forth, DOS, and BIOSes.
Issue 32 may explain FCBs for DOS, which I need to learn about... Issue 64
has an article on SmallC. Interesting, it also has the classic "Moving
Forth" series of articles by Brad Rodriguez. Ah, I bet the article in Issue
81 interested you...
Thanks again,
Rod Pemberton
While Brad Rodriquez's Moving Forth series is a gem, I think the real gem is
the ATA, or IDE interface, articles in 63, 64.
RP
Oh, I see there's a problem, I guess I never fully checked this out.
The problem for my attempt, just today, is INT 19h at c5lib exit:.
The solution for me under dr-dos 6 was to change that INT 19h
statement to JMP 0. That'll only work for a ,COM however. To keep
traceability on c5lib.c I renamed it to c5libdos.c and changed the
#include C5LIB.C at the end of CCN8 to #include C5LIBDOS.C, that
should largely do it. That change needs to be done for your dos apps
c5lib too.
> SmallC needs to include c5lib currently and run in a dosbox. I.e., no
> real-mode DOS applications. I compile mostly with DJGPP because I can run
> the applications in DOS or a Win98 dosbox, whichever I need. Win98 has
> better memory management etc., so the applications typically run faster.
> IIRC, you were looking at an Int 0x21 version. I may look to see what it
> takes to port yours to GCC and/or Int 0x21. We'll see what happens...
>
> 3) I was having some issues with the epilog/prolog and/or ESP/EBP
> strackframe code. I didn't find the error. I don't know if it is in SmallC
> or in c5lib. If I can bootstrap without c5lib by using other code, then I
> know where the problem is.
>
hmm 32-bit? still .COM or are you trying to produce an .exe version?
I haven't been successful in building an .exe version of small-c _self-
compile_ yet, but I have been successful in building other pure nasm
apps into .exe versions that operate properly under the codeview
debugger.
> 4) Psychological irrationalities that must be satisfied... ? ;-)
> Sometimes, the problem is all there is...
>
Be kind to yourself, put it under the general class of 'Discovery'
> > > I did notice that parse() parses pre-processor commands _after_ other C
> > > stuff... Odd. I'll probably reorder that...
>
> > I guess, but those 'else if's are the poor man's switch cases, only
> > one is activated per while loop, with newfunc() being the default
> > case.
>
> I was thinking about precedence, i.e., pre-processor processing is normally,
> or in theory, completed prior to, or takes precedence over other parsing.
> However, the '#' syntax probably nullifies any real concerns there. It
> shouldn't match other syntax... Although, I'm not big on "it shouldn't".
> FYI, IIRC, ANSI C allows whitespace between # and pre-processor command. I
> don't think it's a great idea to extend pre-processor further, it should be
> separate, IMO. Although, I would like #if <value> and #endif, maybe #ifdef,
> since SmallC is "self-contained".
>
> > I haven't hardly looked at small-c in quite a while, too busy
> > with other little projects.
>
> Yeah, anything cool?
>
-uncool tedium of fat12 functions aliasis, for Mike Gonta's aeBIOS. I
thought, once the file system functions are supported, I'd move that
interpreter work over to it. I never dug deep into the fat
filesystem, either as it was or as it is now. I run into a couple of
surprises, plus an error in my code I haven't isolated yet.
> > I ran across some old TCJ issues with a four part series
> > on Threaded Code, really forth, that you may be interested
> > in knowing about..
>
> Thanks. I'll definately take a look.
>
> Yeah, I'm still trying to get some of the C code removed from the backend of
> my Forth interpreter... More Forth, less C - although it'll still be a C
> program. I've let that problem sit and age for a while. :-) I was trying
> to do it incrementally, but doing so meant I had to keep creating both C and
> Forth variables to keep everything sync'd between the two. Ugly. Real
> ugly. Not recommended ever. Basically, they are two separate environments
> that must work together, at the moment. "I've got to 'wash' that C right
> out of my Forth! Ahem..." I'm waiting until a spot of brilliance shines
> upon the project, or I get up the courage to just go all out and fix the
> remaining issues by brute force.
>
Yeah, not enough time in the day..
Steve
> Rod Pemberton
I don't have control over the site, nor the contents, you will need to
report your problem to the owner.
Steve
I guess you mean regarding the unofficial cp/m website. Yeah, too bad
Tim is no longer with us, he was a big help to alot of folks. I had a
couple of email exchanges with him sometime after this, but I wasn't
too involved until Gaby picked up the reins, and I located a copy of
cp/m-86 for the ibm pc, in 1999 or 2000.
Steve
Saved that solution for when I get back to it... Thanks.
> > 3) I was having some issues with the epilog/prolog and/or ESP/EBP
> > strackframe code. I didn't find the error. I don't know if it is in
SmallC
> > or in c5lib. If I can bootstrap without c5lib by using other code, then
I
> > know where the problem is.
> >
> hmm 32-bit? still .COM or are you trying to produce an .exe version?
>
Oh, yes, compiling or bootstraping with DJGPP (GCC) would be 32-bit. I
didn't consider that. I do have a simple DPMI startup in NASM I could slap
on the front. It works (or seems to) with Win98's DPMI support and DJGPP
compatible DPMI hosts. I was thinking about dropping it into a TSR and then
allowing .com's with a two-character combination, like MZ for .exe's, to
trigger the DPMI startup code. I'm not sure about all the details of
redirecting and enhancing DOS' Int 21h, 4Bh execute code service. I may
need to locate a good book on DOS' design. Someday, maybe...
> > > I haven't hardly looked at small-c in quite a while, too busy
> > > with other little projects.
> >
> > Yeah, anything cool?
> >
> -uncool tedium of fat12 functions aliasis, for Mike Gonta's aeBIOS.
>
How's aeBIOS working out for you? I've not done anything with it.
Waiting to see what Mike does with it, e.g., generic 32-bit BIOS or 32-bit
DOS or port DJGPP, etc.
> I thought, once the file system functions are supported,
> I'd move that interpreter work over to it.
>
?
Ok, you lost me... Uh, which interpreter?
> I never dug deep into the fat filesystem, either as it was or as it is
now.
>
I've only read about FAT12/16. It seemed easy from what I've read anyway.
Rod Pemberton
>> -uncool tedium of fat12 functions aliasis, for Mike Gonta's aeBIOS.
>>
>
> How's aeBIOS working out for you? I've not done anything with it.
>
> Waiting to see what Mike does with it, e.g., generic 32-bit BIOS or 32-bit
> DOS or port DJGPP, etc.
aeBIOS will always be a BIOS interface. The current version is a 32 bit
protected mode native motherboard real mode BIOS extender. In other words
aeBIOS facilitates the use of the BIOS by PM32 BIOS based programs. These
would include PM32 BIOS based operating systems and standalone utilities.
I've been studing the feasibility of porting clone versions of CP/M and DOS
1.0.
So far I've ported the RM16 hobby OS - MikeOS to PM32.
http://board.flatassembler.net/topic.php?t=12381
> I've only read about FAT12/16. It seemed easy from what I've read anyway.
FAT32 is just as easy if the bells and whistles are left out.
I'm currently working on FAT32 support for aeBIOS.
A simple RM16 FAT32 read file driver is part of the Real Mode FAT32 USB Boot
Loader
http://board.flatassembler.net/topic.php?p=127245
Mike Gonta
look and see - many look but few see
I thought so (DJGPP is 32-bit). Does it do .com's? The reason I ask
is that the memory layout is different for .exe, so that Call5 won't
work for .exe unless it hand crafted into a .bin where the MZ header
fields are carefully done to equate to a small model where the MZ
header is 100h bytes followed by code org`d at 0100h and data+stack.
The MZ header of 0100h size is replaced by the dos loader with a PSP
of the same size. In this careful case, Call5 will work because the
call is in the code section for that address.
The 'natural' memory layout for an .exe, according to what Codeview
expects is:
[data]
[code]
[stack]
-as separate values for DS, CS, SS so that the replacement of the MZ
header by the loader with a PSP is outside addressability of CS, so
Call5 won't work -- the absolute far address the Call5 vectors to,
must be far called directly instead.
-So, of course, int 21h is the more viable option, but I haven't
finished the io-lib for it because ((1)-below) had grabbed my
attention.
> didn't consider that. I do have a simple DPMI startup in NASM I could slap
> on the front. It works (or seems to) with Win98's DPMI support and DJGPP
> compatible DPMI hosts. I was thinking about dropping it into a TSR and then
> allowing .com's with a two-character combination, like MZ for .exe's, to
> trigger the DPMI startup code. I'm not sure about all the details of
> redirecting and enhancing DOS' Int 21h, 4Bh execute code service. I may
> need to locate a good book on DOS' design. Someday, maybe...
>
> > > > I haven't hardly looked at small-c in quite a while, too busy
> > > > with other little projects.
>
> > > Yeah, anything cool?
>
> > -uncool tedium of fat12 functions aliasis, for Mike Gonta's aeBIOS.
>
> How's aeBIOS working out for you? I've not done anything with it.
>
(1)
It's fine, I began to work with it in feb, I'm at the point of needing
to do the Fat12 pseudo os file functions. The light went on then when
I considered how its flat memory relates to the situation of the flat
memory on the 8080, or Z80, and CP/M-80 came to mind. -not to do cp/m
specifically, but the same similar issues arise on deciding on a
memory map, and strategy of loading transient executables.
The issue is: sub-directories. Although keeping things simple by
restricting files to root seems ok, user file operations from the
windows side, like copying a directory folder and files to the
diskette did some unexpected things for me. Like creating a "volume
'wide-char' name" in the directory with a zeroed starting cluster
number and shifting the fat by a paragraph (it seems). - just
scratched the surface (and it smells :)).
> Waiting to see what Mike does with it, e.g., generic 32-bit BIOS or 32-bit
> DOS or port DJGPP, etc.
>
So we have Mike's own words! See? ;)
> > I thought, once the file system functions are supported,
> > I'd move that interpreter work over to it.
>
> ?
>
> Ok, you lost me... Uh, which interpreter?
>
The unnamed interpreter I've done some work on (kinda a simpler small
C).
>
>
> > I never dug deep into the fat filesystem, either as it was or as it is
> now.
>
> I've only read about FAT12/16. It seemed easy from what I've read anyway.
>
The thing is, it probably would be if we were talking about dos 2.0,
but nowadays we're talking about a mangled algorithm of backward
legacy support on a LFN filesystem. -it remains to be seen how easy..
Steve
> Rod Pemberton
I should've read what you said instead of saving it...
The problem with MS-DOS v7.10 (Win98SE), is a failure to open a file for
writing. E.g., when small C asks "Output filename?", after inputting a
file, it returns this error in real mode DOS:
File Not Found for writing, Creating..
fopen result reports null.
;Line 0, (start of file) + 0XX: Open Failure!
That failure doesn't happen in a Win98 console "dosbox" window.
RBIL says FCB functions are not supported for FAT32. This note is in RBIL
Int 21h, AX=0h or AH=16h:
"(FAT32 drive) this function will only succeed for creating a volume
label; FAT32 does not support FCBs for file I/O"
If RBIL is correct, then I would need a non-FCB c5lib for use with FAT32.
That's probably the issue, since my drive is FAT32.
It's interesting that FCBs work in a Win98 console "dosbox" window, which (I
assume) would imply that 98 is using NTVDM. But, there doesn't seem to be
NTVDM file in 98. If Win98SE was using MS-DOS v7.10 for DOS under Windows,
I'd think I'd be seeing the same problem in a console window, but I'm not.
The additional NTVDM like functionality must be "in there" somewhere...
Sorry, it seems we discussed some of this back in spring '09!
Rod Pemberton
> File Not Found for writing, Creating..
> fopen result reports null.
> ;Line 0, (start of file) + 0XX: Open Failure!
>
Good to see the error messages are working, I'm glad I left 'verbose'
as the default.
> That failure doesn't happen in a Win98 console "dosbox" window.
>
> RBIL says FCB functions are not supported for FAT32. This note is in RBIL
> Int 21h, AX=0h or AH=16h:
>
> "(FAT32 drive) this function will only succeed for creating a volume
> label; FAT32 does not support FCBs for file I/O"
>
That's both interesting and odd.
> If RBIL is correct, then I would need a non-FCB c5lib for use with FAT32.
> That's probably the issue, since my drive is FAT32.
>
Yes, thanks for reporting this. I'll make sure I don't mix the FCB and
Handle functions for the doslib version.
> It's interesting that FCBs work in a Win98 console "dosbox" window, which (I
> assume) would imply that 98 is using NTVDM. But, there doesn't seem to be
> NTVDM file in 98. If Win98SE was using MS-DOS v7.10 for DOS under Windows,
> I'd think I'd be seeing the same problem in a console window, but I'm not.
> The additional NTVDM like functionality must be "in there" somewhere...
>
I wouldn't bet on that. As far as fcb support, I suspect its a case
of legacy driver wrapper on top of legacy driver wrapper, but who
really knows. Fat32 era would've been about the time msft claimed the
wish to dump msdos legacy support. I guess it took them until vista
to orphan it.
Steve
I had this same error under XP's cmd.exe this weekend for a build I
did of CCN8A.C, but the cause was that I included the wrong c5lib for
it. One version is for when AX is the Primary, and BX is the
secondary register, and the later versions are for when BX,DX are
primary,secondary. -this doesn't sound like your issue exactly but you
might want to check which abi, to be sure.
To clarify things for CCN8A.C I've updated the project page with all
the files used, and build instructions for it:
http://www.project-fbin.hostoi.com/CCN8_HTM/RT_CCN8.HTML
http://www.project-fbin.hostoi.com/index.htm
-I haven't integrated any of the commented-out stuff in CCN8A.C, from
the the prior CCN8.C, just clarified that the C5LIBA.C is the io lib
to be included with it. I've changed C5LIBA.C to exit() using Call5
'program terminate' instead of int19h for consistency between real
mode pcDos and cmd.exe, and I've changed the PROLOG.NSM 'return from
main() to exit' to the same method, while I was at it.
Steve
Yes. Apparently, it is working for you with at least one real-mode DOS.
So, I strongly suspect the FCB issue noted by RBIL.
> I had this same error under XP's cmd.exe this weekend for a build I
> did of CCN8A.C,
Interesting... That could imply the later version is fixed, or maybe
prolog/epilog related...
What happens on XP with the first version released? It's on your "Project
Small-C" page. Does it work or fail?
> but the cause was that I included the wrong c5lib for
> it.
>
I'm sure I've got the correct one.
> One version is for when AX is the Primary, and BX is the
> secondary register, and the later versions are for when BX,DX are
> primary,secondary. -this doesn't sound like your issue exactly but you
> might want to check which abi, to be sure.
>
IIRC, it's the AX version. It's c5lib.c ver. 0.2.3. This is on your the
"Project Small-C" page.
> To clarify things for CCN8A.C I've updated the project page with
> all the files used, and build instructions for it:
>
I haven't downloaded that version... I'll do so. I let you know if it
works or fails, hopefully, fairly soon.
> I've changed C5LIBA.C to exit() using Call5
> 'program terminate' instead of int19h for consistency
> between real mode pcDos and cmd.exe, and I've changed
> the PROLOG.NSM 'return from main() to exit' to the same
> method, while I was at it.
>
Ok.
Rod Pemberton
[more SNIP]
> > To clarify things for CCN8A.C I've updated the project page with
> > all the files used, and build instructions for it:
> >
>
> I haven't downloaded that version... I'll do so. I let you know if it
> works or fails, hopefully, fairly soon.
>
Ok, NASM'd the .NSM for CCN8A. Same issue.
BTW, CCN8A seems to have Posix EOL? It wraps like just LF instead of
CRLF... I didn't confirm.
Rod Pemberton
Thanks for the great feedback, Rod.
Yes, I didn't find a pertinent difference between the two source
groups to account for the difference in behavior, probably some subtle
change I'd missed in C5LIB versions. Both nl() functions are the
same, which outbyte(10), i.e., LF. I normally don't notice the
newline difference because I use WordPad and it auto converts for
display purposes. Notepad doesn't auto convert, hence the issue.
NASM accepts either form of newline ending, thankfully. Oddly, using
WordPad and saving the .nsm file as .txt auto converts it to CR,LF
form.
However, the permenent solution is to change nl() in CCN8A.C to:
nl() { outbyte(13); outbyte(10); } /** CR,LF 0Dh,0Ah 13,10 **/
Steve
I'm not sure if you saw it, but someone posted a link to alt.lang.asm, that
you might be interested in:
>>Don't know if you guys already have this but Dr. Dobbs has a nice package
of
>>the small C article and the C code (hmmm no assembly, why not?) in ISO
>>format freely downloadable at
>>
>>http://drdobbs.com/embedded-systems/184415519
>>
The direct link is here:
(if your browser has problems with that webpage as mine did)
http://i.cmpnet.com/ddj/sdmediagroup/images/sdm1123195158574/ddj_devnetwork_small_c.zip
I was not able to use 7-zip to open the .iso in Windows, but IsoBuster does.
You can also loop mount with *nix.
Rod Pemberton
Thanks for reposting the link. I was able to download it, and
finally, write its .iso image. It is not only the book in html form,
but also Hendrix's asm in c is there, and Andy W. K. Yuen's concurrent
C stuff. -so thanks again!
Co-incidently, I've been working on pcdos lib for small-c as an
alternate to c5lib, to build .exe's.
Steve
>
>
> >>Don't know if you guys already have this but Dr. Dobbs has a nice package
> of
> >>the small C article and the C code (hmmm no assembly, why not?) in ISO
> >>format freely downloadable at
>
> >>http://drdobbs.com/embedded-systems/184415519
>
> The direct link is here:
> (if your browser has problems with that webpage as mine did)
>
> http://i.cmpnet.com/ddj/sdmediagroup/images/sdm1123195158574/ddj_devn...