GST has chipped in with a C compiler for the QL, called QC. It implements a subset of C, says Leon Heller.
QC On Trial
GST has chipped in with a C compiler for the QL, called QC. It implements a subset of C, says Leon Heller
When the QL was launched, Sinclair promised a C compiler. But the official Sinclair product has not yet materialised, and GST, the Cambridge company which developed the 68K/OS Operating System for the QL, has now brought out its own - it's a familiar story.
Rather than implement an all-singing, all-dancing, full C compiler, GST took the source code of the Small C 8080/Z80 Compiler, originally published in Dr. Dobbs' Journal of Computer Calisthenics and Orthodontics, and modified it to run on the QL to produce 68000/68008 code.
The result, QC, is a compiler that implements a subset of the C language as described in the C programmer's bible, The C Programming Language, by Kernighan and Ritchie. The main omissions are floating point, structures and multi-dimensional arrays.
What is C?
For those readers not already addicted to C, it is a relatively simple expressive general-purpose programming language which allows the programmer to produce concise, highly structured source code. This compiles to compact, fast machine code. C is ideally suited to systems programming - writing operating systems, editors and compliers - but it also used for applications programming. It is one of the most portable languages as C programs written for one machine usually run on another with few, if any, changes. QC programs which don't use any features specific to the QL should run on most other machines with a C compiler. Lots of public-domain software written in C is available as source code from the C Users Group and the CP/M Users Group software libraries.
First Impressions
QC comes on two Microdrive cartridges with two blank cartridges provided for backup. An A5 ring binder contains the 73-page user manual, supplemented by a book on C (A Book on C by R. Berry and B. Meakins)
One cartridge (QC1) contains the C Compiler, Assembler, the standard Sinclair Linker Control file, a SuperBasic program to drive the compiler, assembler and linker, and a clone program. The second cartridge (QC2) contains two library files, a standard I/O header file, a sample program, and a clone program.
The package runs on a standard QL, but is much easier to use if you have the QL Toolkit, due to the implementation of pipes, which means the output of one program can be used as input to another without needing temporary files. There's no text editor, but most users probably have one already. I have been using the Metacomco editor; masochists could even use Quill.
In Use
QC is written in QC, by the way and, like most C compilers running on micros, compiles to assembly language. This is first assembled, then linked with a library to produce a program which can be EXECed in the usual manner. A comprehensive library is provided, which as well as usual functions for input/output, opening files, etc, also includes many features available in SuperBasic, such as sound generation, windowing and string handling. Direct access to QDOS functions is provided, and 'in-line' assembly language may be employed using the #asm and #endasm directives.
Assuming you have your program residing in source code form (a file called "fred-c" on cartridge QC2 in drive 2, with cartridge QC1 in drive 1, you compile the source by typing "exec_w mdv1=qc" to boot QC. When prompted for a command line, you just type "mdv2_fred", and the program is translated into an assembly languge file called "fred_asm", on drive 2. This is assembled by typing "exec_w mdv1_qasm", followed by "mdv2_fred", when a command line is requested.
The relocatable binary file produced by the assembler, "fred_rel", must now be linked with the runtime library. This is done by first typing "exec_w mdv1_link". The linker requests a command line, and "mdv2_fred mdv1_qc_link -nolist" produces a file called "fred_bin" on drive 2, which may then be executed with "exec" or "exec_w".
The process can be menu-driven using a SuperBasic program called "compile", supplied as part of the package.
QC supports separate compilation: functions may be compiled separately and linked with the main program to create your own function libraries.
Error messages given by the compiler and assembler are informative, but the same cannot be said of the linker. This merely outputs "undefined symbols" when it comes across an unresolved reference, necessitating close examination of the optional linker listing file, which can be rather large.
A Typical Program
This is part of a program which emulates a (very) dumb terminal, wihch illustrates some features of QC.
#include
define ESCAPE 27
int*CHAN,fd;
main(){
int c;
baud(300);
chan = fopen( "ser2er", "w" );
fd = *chan;
if( fd == 0 ){
puts( "Serial I/O open error" );
exit(0);
}
while(1){
c = serin();
if(c != 0){
c =c & 127;
putchar(c);
fflush(std out);
}
c = poll(0);
if(c != 0 ){
if( c== ESCAPE) exit(0);
serout(c);
}
}
}
serout(c)
int c;{
int regptr[8];
regptr[0] = 5;
regptr[1] = c & 127;
regptr[3] = -1;
regptr[4] = fd;
trap3(regptr);
}
serin(){
int regptr[8];
regptr[0] = 0;
regptr[3] = 0;
regptr[4] = fd;
trap3(regptr);
if( regptr[0]<0 ) return (0);
regptr[0] = 1;
regptr[1] = 0;
regptr[3] = -1;
regptr[4] = fd;
trap3(regptr);
return(regptr[1]);
}
Verdict
QC lacks some of the features of a full C compiler, but it can be used for serious work and is ideal for learning the language. It makes excellent use of the QL's unique features.
Report Card
Features 4/5 Documentation 4/5 Performance 4/5 Overall value 4/5