blog:ql_dev1

This is an old revision of the document!


Sinclair QL Development Tools

There are a range of development tools and languages for the QL, including the built-in SuperBASIC. But I am more interested in using the same type of tools that I use for the NEC PC-98, MS-DOS, X68000 and more; a reasonably standards compliant C compiler, assembler and linker.

There are a few C compiler options for the Sinclair QL - which are summarised nicely here: http://www.dilwyn.me.uk/c/index.html

I touch on a few of them, including the one I am using (C68, in it's modern cross-compiler incarnation) below.

Purported to be the main C compiler for Sinclair QL systems. This is the original version intended to run on the QL itself.

A port of C68 to DOS, Windows and Linux systems was made in the late 90's to earl 2000's. Unfortunately it has bit-rotted quite badly and does not run on any current systems. The Git repository above is a reworked, cleaned up version that compiles perfectly on modern 64bit Linux systems.

As suggested, this runs as a cross-compiler; targetting the Sinclair QL QDOS runtime with the convenience of using all of the modern development tools, source code revision of a GNU/Linux system.

I've posted a pre-compiled version of the toolchain, with the original C68 runtime libraries (crt.o, libc.a et-al) and system headers, below.

Sample C68 Makefile

You can of course use standard GNU Makefiles alongside C68, here's a basic one that compiles a single binary from two .C source files, as you would normally do with anything of reasonable complexity.

# Sample makefile for C68 projects

#################################
# Locations and name of compilers 
# and friends
#################################
PREFIX = /opt/toolchains/qdos
PATH = ${PREFIX}/bin:$PATH
CC = ${PREFIX}/bin/qcc
LD = ${PREFIX}/bin/qld
AS = ${PREFIX}/bin/as68
CPP = ${PREFIX}/bin/qcpp

#################################
# Paths to additional headers and
# library files
#################################
#INCLUDES = -I./my_includes -I./other_includes
INCLUDES = 
#LIBS	 = -L./my_libs -lmylib
LIBS = 

#################################
# Compiler flags
#################################
ASFLAGS = 
LDFLAGS = 
CFLAGS = -O

#################################
# What our application is named
#################################
TARGET = game

#################################
# Targets to build/run
#################################
all: $(TARGET)
#dev:
#test:

#################################
# Object files needed to build our 
# main application
#################################
OBJFILES = test.o other.o

#################################
# Main application target build recipe
#################################
$(TARGET):  $(OBJFILES)
	$(LD) $(LDFLAGS) $(OBJFILES) $(LIBS) -o $(TARGET)

###############################
# Clean up
###############################
clean:
	rm -f *.o
	rm -f $(TARGET)

################################
# Each C source is compiled to
# an object file, to be linked
# as a single binary, above.
################################
test.o: test.c
	$(CC) $(CFLAGS) $(INCLUDES) -c test.c
	
other.o: other.c
	$(CC) $(CFLAGS) $(INCLUDES) -c other.c

This has the potential to be a great resource for people such as myself who are primarily unix developers. Sadly, this was a project started a long time ago, and as such, is based on a horribly dated version of GCC 2.95.3 - almost 20 years old at the time of writing (2021).

As such, it is a real pain to get working on any reasonably modern version of Linux. The project above has attempted to make it easier by building all of the tools inside an earlier Debian-based docker container, but I simply could not get it to work reliably; the install procedure is a bit of a mess of installing components to bootstrap the build of other components, then overwriting various binaries with the stages of later output. It's all a bit of a mess (and no fault of the guy trying to make it easier!).

It should, in theory, build outside of a docker container, and I got it mostly working, but when invoking the built version of gcc, the linker stage of a test C program would blow up with a signal 6 (ABORT).

It's a shame, as other platforms (Atari ST, for example) that are very similar to the QL, have much more modern versions of the GCC

The QL has it's own filesystem and files have attributes which are not directly equivalent to anything on a modern filesystem - storing the size of the amount of memory needed to load the binary, for example. So there are some tools needed to get anything you are working on, say in a Linux filesystem, into a QL-native format.

  • qlzip
    • Any binaries produced by C68 can be zipped up, have their extended data stored, and then unpacked with the correct data in place using a native QL unzip tool.
  • blog/ql_dev1.1639486289.txt.gz
  • Last modified: 2021/12/14 12:51
  • by john