// Version 0.50 5/18/2000


                B-Flat, a Crude but Useful "C" Compiler


B-Flat is copyright (C) 1998,2000 by Ken Martwick.


  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

To contact the author send electronic mail to kenm@efn.org

or snail mail to

Ken Martwick
38776 Place Road
Fall Creek
Oregon 97438 USA

***NOTICE*** Major changes made since Version 0.30 (the last published
version) are described in the file "changes.doc".

What is B-Flat?
************

     B-Flat is a simple 32-bit "C" compiler that implements a subset of 

standard "C".  While it shares some features with ANSI C, such as the

need for function prototypes, it is not necessarily in compliance with

the ANSI standard.

Why B-Flat?
********

     B-Flat is the result of an unsuccessful search for a free, compact

"C" compiler that could produce flat-form 32-bit executables similar to

MS-DOS 16-bit "com" programs for use with Michael Tippach's WDOSX DOS ex-

tender.  It has since been modified to produce "com" programs to run in

"flat real" mode (4 Gigabyte segment limits in "real" mode!). Also, it is

certainly an excellent learning experience!  It is still capable of pro-

ducing programs for "WDOSX", but development of the "newlib" function

library (see below) is far behind the "flatlib" library.  Many of the

functions from "flatlib" could be used without change.

     The "compile option" Q has been added to support Tomasz Grysztar's

excellent "fasm" assembler; it is free and is available on the web at 

omega.im.uj.edu.pl/~grysztar/fasm/fasm10.zip.

Hardware Requirements:
**********************

     The supplied "b.exe" (the compiler itself) was built using "DJGPP",

Mr. D. J. DeLorie's excellent DOS extender and compressed using "UPX",

an executable file compressor by Mr. Laszlo Molnar.  As such, the com-

piler cannot be run on any computer without at least an 80386.  It may

be possible to modify the source code to allow it to be compiled and

run directly under MS-DOS or an equivalent OS; at present there are

single data arrays exceeding 64 Kbytes, which are not possible in "real"

mode.  A math coprocessor is not needed.

Software Required:
******************

     In addition to the programs in this package ("b.exe", "datopt.exe",

and "fixlabel.exe" (run by "datopt.exe")), The "NASM" or "fasm" assembler

and (if 32-bit "Protected Mode" programs are desired) the "WDOSX" 32-bit

extender are needed.

All are free and are available on any "simtelnet" mirror.  NASM is in the

directory pub/simtelnet/msdos/asmutil as nasm???.zip where the question

marks are the version number.  WDOSX is in the directory pub/msdos/pgmutl

as wdosx???.zip.

     The (included) programs "quickopt.exe" and "qlabel.exe" are used with
     
the "fasm" assembler.     

     As mentioned in "changes.doc", functions ("a20_on" and "go_flat") are

now in "flatlb" and the new "fasmlib".  So, "UNREAL.EXE" is not needed.  If 

programs are compiled to use the "fasm" assembler, the greater bulk of NASM

can be avoided.

What does it do?
****************

     B-Flat compiles a single "C" program into assembly-language as a non-

relocatable binary image.  This is equivalent to an MS-DOS "com" program;

The assembly-language syntax used is that of "NASM".  NASM is an excellent

and complete assembler that is freely distributed and available on the

many "SimTel" mirror sites.  The code B-Flat produces is not compatible

with MASM or TASM!  It will not, of course, run on a computer earlier than

the 80386.

Using "B-Flat":
***********

     To use "B-Flat" to produce "myprog.asm" for "flat reaL" mode from

"myprog.b", simply type "b myprog f" and <enter>.  The extensions are

inherent in the program.

     To use "B-Flat" to produce "myprog.asm" for WDOSX from "myprog.b",

simply type "b myprog" and <enter>.  The extensions are inherent in the

program.

     The only "preprocessor" directive is "#libname", which allows use of
     
a "function library".  See the sample files "flatlib.h", "flatlib.lib",

and "fed.b" for an example of usage.  Only the functions actually used

are incorporated in the program.  However, all variables defined in the

"lib" header file are incorporated in the program.  A simple "optimiser"

program, "datopt.exe" is included which deletes the unused variables.

Running "datopt myprog" after "b myprog" will produce the "optimised" 

"myprog.asm" prior to the assembly step (see below).  "B-Flat" generates

up to three temporary files during execution.  These should never be seen

in normal operation, but will remain in the case of an error.  The temporary

files can be helpful for debugging purposes.

     For "flat real" mode, the output of "B-Flat" is an "asm" file with

an origin at 0x0100 and a standard "MS-DOS" exit code.  The command-line

to assemble "myprog.asm" is "nasm -f bin -o myprog.com myprog.asm".  The

resulting "myprog.com" will run only if the computer is in "flat real"

mode.  Calling the "go_flat" first will guarantee this, though two of

my PC's with MS-DOS 6.20, "himem.sys", and two quite different versions

of AMI BIOS boot in "flat real" mode.

     To compile a "flat real mode" program using the fasm assembler, type

"b myprog q" and then "quickopt myprog".  To assemble the program, the

syntax "fasm myprog.asm myprog.com" is used.

     For WDOSX, the output of "B-Flat" is an "asm" file with an origin at

0x0000 and a standard "MS-DOS" exit code.  The command-line to assemble

"myprog.asm" is "nasm -f bin -o myprog.exe myprog.asm".  The resulting

"myprog.exe" WILL NOT RUN!  It must first have a 32-bit "stub" added with

Michael Tippach's "stubit.exe" program!  Simply type "stubit myprog.exe"

to produce a 32-bit executable program.  All of the above steps could

certainly be accomplished with a simple batch file.



Usage / Limitations:
********************

NOTE: B-Flat expects "C++" comments, in which each comment begins "// "!

These are currently at least supported by many "C" compilers and may

be the only good that ever comes from that bizarre "language".

     B-Flat, at present, supports "char" (8-bit) and "int" (32-bit) vari-

ables.  Both are unsigned.  Character strings are also supported us-

ing the form "char text[50];" or "char text[] = {"This is a string!"};.

Integer and pointer arrays are also available.  Both "for" and "while"

loops are implemented, but neither is yet complete.  A while loop can

be of the form "while(1)" which has no means to exit by itself, or of

the form "while(varname)".  The latter form terminates when "varname"

has a zero value.  "For" loops are of the form "for(n = 0; n < 30; n++)"

or "for(n = 97; n > varname; n--);".  "n" is initialised to the start-

ing value and is incremented or decremented each time through the loop.

Only the "<" and ">" comparisons are available.  The loop exits when

the second value is reached.

     Math / assignment statements may be of the form "a = b;" or

"a = b + c;"; either b and/or c may be either decimal numbers or

hexadecimal numbers in the standard 0xF1C3 form.  The "+" may be

be replaced by "-", "*", "/" or "%" (modulus).  Subscripts may be

used on the right for character strings.  Also available are the

"shift" operations ">>" and "<<" as in "outval = inval << 3".

     "If" tests are formed in the conventional way; the "comparison"

operators are "<", "<=", "==", "!=", ">=", and ">".  "If" tests

cannot have more than one term.  An "else" statement must appear

on the very next line after an "if" clause to be coded correctly!

     A special "if" test may be used to escape from any loop; it

tests a variable and exits the loop if its value is non-zero.  It is

of the form "if(varname) break;".  The form "if(!varname) break;"

is also available.

     A "switch" may be used to control program execution based on

the value of an integer variable.  Each "case" can be followed by

any number of legal statements, each on a separate line.  The case

is terminated by a "break" statement.  Multiple cases preceding a

single group of statements are supported as is a "default" code sec-

tion.

     Functions can be of type "char", "int", or "void".  Values for

non-void functions are returned in AL or in EAX.  Calling parameter

passing is by way of variables created by preceding the name used in

the prototype with an underbar.  At present, the function must refer

to the parameters in this way.  Pointers may also be passed to a func-

tion.  "Local" variables of types "char", "char *varname" (pointer to

character), and "int" within a function are supported.  All "local"

variables are initialised to a value of zero.  Both single ASCII char-

acters 'c', and quoted strings "This is a string" may be used in func-

tion calls when appropriate.

     In general, pointers are supported, including pointers to int-

egers.  They are handled in a slightly different way than in ANSI

"C".  I feel the handling is both more sensible and more easily

understandable!  (It's also easier to program!)  Assuming a char-

acter pointer "ptr" and a character array "buff", asserting "ptr

= &buff;" will cause "ptr" to contain the address of "buff".  Thus

*ptr is the first character in "buff".   However "ptr = buff" will

cause "ptr" to contain the first byte of "buff" plus three more bytes

which are undefined!  Generally, pointers are integers and may be

treated as such mathematically.

     Any program line starting with "_asm " is passed directly to

the output file; errors in these lines will be reported by the as-

sembler.

     The somewhat crude parsing techniques now used encourage an

"open" style of programming; for instance a "{" or "}" on the same

line as other code will effectively eliminate the other code!

Similarly a statement without "white space" such as n=0 will pro-

duce an error or incorrect code.

     It must be stressed that error-checking is limited.  If the

compiler can make any sense of a line of code, no error will be

reported.

     If the compiler does find an error, it will print an error

statement to "stdout" and exit.

Building B-Flat:
************

    As mentioned above, development is being done using "DJGPP".

A simple "makefile" is provided.  For reasons not known to me,

gcc v.2.7.2.1 produces erroneous code.  I am now using gcc v.2.8.0.

As a test, the program was also compiled under Slackware Linux

v.1.2.13 using "gcc" v.2.6.3.  The code produced by the Linux ver-

sion was identical to that produced by the DJGPP version.  It is

possible that a commercial "C" compiler could be used to compile

"B" to run under Windows.  Borland C would seem most likely to com-

pile it directly since some functions from "conio.h" are used.

If it should be desired to build a 16-bit version of "B", the code

must be modified.  Firstly, the "buff" array is not really needed

at present; the current compiler uses only a single pass.  A line-

by-line reading of the source file could be implemented with little

difficulty.  The "loop" structures would present more of a problem;

perhaps they could be moved to a temporary file on RAM-disc.  It is

not clear that they are big enough as they are!

Bugs, etc.:
***********

     Please report bugs, successes, suggestions, and so forth to

either of the addresses listed at the beginning of this document.

It cannot be emphasized too much that this program is very much a

"work in progress" and is very certainly BETA software!  Treat it

as if it had been produced in Redmond, Washington!


