|
project...
Sphinx
|
|
Logo by
Michael Sheker
Partially updated
May 31, 2003
|
Sphinx C-- is a programming language that combines C and assembly
language. It runs at the DOS commandline and can generate applications,
library files and drivers for 16-bit and 32-bit DOS, 32-bit MS Windows, and
MenuetOS, and probably more. In this page I introduce C-- and how it can
be used for MenuetOS and Windows.
Why write apps in C--? In a nutshell, C-- has low-level features, placing it somewhere between
C and assembly. Sometimes a high-level language such as C can be very frustrating
when you want to write code that accesses the underlying hardware architecture,
or utilises the architecture for optimum efficiency. For example, I have used a C compiler called MACC to
write applications for MenuetOS, and to call a software-interrupt routine,
passing parameters via registers, involves first pushing the parameters onto
the stack, calling an inline asm routine which transfers them to registers
then calls the interrupt -- which is very inefficient. Often a C compiler
places frustrating restrictions on in-line assembly code -- for example, MACC
will only allow asm code outside a C function. C-- releases you from the
straight-jacket, into a world of unfettered coding.
Sphinx C-- was originally developed by a Canadian, Peter Cellik, but he stopped
working on the project in 1996. The main person who has continued the project
is a Russian person, Michael Sheker, and his website is: http://c--sphinx.narod.ru/indexe.htm
At this site you will find the C-- compiler, Phoenix Workbench
(IDE), documentation and many examples.
Peter Cellik's documentation on C-- was last updated in 1996. Michael's documentation
is partially translated from Russian to English and much is still in Russian.
As I found the translated Russian difficult to read, I decided that myself
and everyone would benefit from a nicely written documentation file in English.
So, here it is:
Sphinx C-- documentation: http://www.goosee.com/cmm/c--doc.htm
The remainder of this page is in two parts: usage of C-- for MenuetOS, and for MS Windows. Firstly, MenuetOS...
|
C-- for MenuetOS
|
MenuetOS is a 32-bit preemptive multitasking multithreaded
operating system for 386+ CPUs and IBM-compatible PC architecture, complete
desktop GUI, TCP/IP networking, CDROM, keyboard, mouse, sound, video
interfaces, realtime I/O, size only 61K bytes. International open source
project. Complete with source fits on a floppy disk.
I have a webpage dedicated to MenuetOS:
MenuetOS webpage: http://www.goosee.com/menuetos/
MenuetOS itself is written in assembly language and assembled with FASM or
NASM. Applications may also be written in assembly language or a high-level
language. The requirement is that the generated file be a flat 32-bit binary
file with a small header (this header is provided in the file 'msys.h--'
in the following example).
One problem is that some recent documentation is in Russian, and it took
me awhile to figure out how to compile an example application for MenuetOS.
It has turned out to be a pleasant surprise, and the same first example that
I developed for MACC/FASM compiles to almost half the size with C--, at 280
bytes compared with 429 bytes for the same example compiled with MACC.
I also made the very pleasant discovery that C-- now supports type 'float',
that is, floating point. I discovered this by examining Michael's "history"
page -- he has an impressive record of consistent work on this project over
the years and addition of excellent features. So, this is a very active project,
very much a plus point.
My simple example
You can download the complete package from the C-- project home page,
but if you just want to see my example application, compile and run it, it's
very simple to do.
Here is my first simple example application: cmm1.c--
Here are all the files you need to compile it: cmm1.zip (196K)
The zip file contains 'cmm1.c--', 'c--.exe', 'msys.h--', and 'startup.h--'.
The latter file doesn't actually do anything, but the compiler 'c--.exe'
needs to refer to it. The file 'msys.h--' has the code for the MenuetOS system
calls -- this file is not complete, and a volunteer would be welcome to add
the rest of the system interrupts to it. I would like to thank Alexey Sugonyaev
who developed this library file, now modified by me, and he gave me
some assistance with getting started.
With these four files in the same directory, all you need to do is type this at the DOS prompt:
C:> c-- cmm1
That's it. The output will be 'cmm1.com', rename to just 'cmm' if you like,
and copy to the MenuetOS floppy disk and reboot. When you have the MenuetOS
desktop, choose
Start -> System -> Prompt
and at the Mash prompt type:
mash> CMM1
Second example
I have also included in the above 'cmm1.zip' file, another simple example
'cpuspeed.c--', that displays the speed of the CPU in MHz.
The source code: cpuspeed.c--
System library file
The file 'msys.h--' has the runfile-header, symbol definitions, structure declarations, and MenuetOS system call definitions.
With regard to the latter, I chose to maintain the exact parameter-passing format as for the registers. For example:
/*
04 = WRITE TEXT TO WINDOW
ebx [x start]*65536 + [y start]
ecx text color 0x00RRGGBB
edx pointer to text beginning
esi text length
ret: nothing changed
*/
inline register void sys_write_text(dword EBX, ECX, EDX, ESI){
EAX = 4;
$int 0x40;
}
You can see here that the first parameter passes both x and y coordinates,
and it would seem "nicer" to redefine the C function so that parameters are
passed something like this:
sys_write_text(xstart,ystart,color,#smsg1,23);
However I decided to keep it very simple for the assembly language programmers
who may also want to use C--. Therefore, parameters are passed exactly as
per each register.
I have always defined the system calls with the registers in the order as shown above, that is, EBX, ECX, EDX, ESI.
Here are examples how sys_write_text() will be used with my library:
sys_write_text(8<<16+8,0xFFFFFF,"C-- CPU speed example for MenuetOS",34);
and
sys_write_text(25<<16+25,0xFFFF80,#smsg1,23);
Always remember that Sphinx C-- evaluates expressions in order from left
to right. There is no operator precedence and parentheses are not allowed.
For example, "(25<<16)+8" is illegal.
More examples for MenuetOS written in C--:
MeFar file manager for MenuetOS, pre-beta, by Alexey: MEFAR.zip
|
C-- for MS Windows
|
I have put together a little Win32 GUI application to show how easy it is.
Here is the application source code: win1.c--
Here is a zip file with "win1.c--", "win1.rc", and "star.ico": win1.zip
To get ready to compile, you need those three files in the same directory.
You will need to have downloaded Michael Sheker's complete package, which
has in it a directory called "win", which has all the header files. You will
need to edit the "#includepath" line in "win1.c--" (see my example below) to wherever you have placed
that "win" directory.
Almost there ... grab "startup.h--" and put it in the working directory also.
Either grab "c--.exe" (the compiler) and put it into the working directory
also, or make sure it's in the DOS search path.
To compile, just type at the DOS prompt:
c-- win1
That's it, you'll get an executable, "win1.exe". The C-- compiler also has an inbuilt resource-compiler and linker.
At the beginning of "win1.c--" (the application source file) you'll see this:
#pragma option w32 //create Windows GUI EXE.
#pragma option J0 //no startup code.
#pragma option dbg //create debug information (separate .tds file).
#pragma option lst //generate listing file.
#pragma option w //enable warning.
#pragma option 3 //386 CPU.
#includepath "c:\progra~2\c--\lib\win"
#include "windef.h--"
#include "winbase.h--" //kernel32.dll
#include "wingdi.h--" //gdi32.dll
#include "winuser.h--" //user32.dll
#include "commctrl.h--" //comctl32.dll
#include "commdlg.h--" //comdlg32.dll
#include "shellapi.h--" //shell32.dll
#pragma option ia //no need "$" or "asm" for inline asm.
#include "win1.rc" //resource file.
The "/ia" option eliminates the need for inline asm code to be prefixed with
"$" or "asm" keywords. This means that the entire assembly language instruction
set become keywords.
The "/j0" option suppresses the startup code and there is a direct jump to
main() when the program executes. This is because I have startup code inside
main() itself.
You can comment this out and the compiler will put in its own startup code
-- examine the generated file "win1.lst" (listing file) to see the output
code.
The "/dbg" creates a file called "win1.tds" and these are symbols that the Borland Turbo Debugger can read. Turbo Debugger is available free from Borland -- see the download link at: http://www.goosee.com/x86/.
If you want to understand more about the structure of my skeleton application,
a good book will be most helpful. You need one that introduces C programming
for Windows using the Win32 API (Application Programming Interface). You do not want a book that describes Visual Basic or C# or C++ or MFC or any kind of object-oriented approach.
There are various online sites that have introductory tutorials, like this one: http://winprog.org/tutorial/.
My little "win1" skeleton is an excellent starting point for much bigger apps. Have fun!
(c) 2002,2003 Barry Kauler http://www.goosee.com/explorer/