TIM-011 gets a C runtime library

2023/12/13

TIM-011 gets a C runtime library

TIM-011 was an 8-bit teaching computer that was ostensibly developed by IMP in what is now Serbia.

Now that https://github.com/filmil/tim011-tools/issues/3 has been fixed, the TIM-011 tools compile and run with a real C runtime library, thanks to the libcpm-z80 library.

It wasn’t easy to get it to compile with bazel, but after plenty of trial and error I managed to pinpoint the correct incantation. I also ended up with a pull request to libcpm-z80 which contains the generalizations needed to get it to compile under bazel.

Here’s what it looks like with a classic hello world program. The hello world program calls printf(), which in turn requires a runtime library to be present and operational.

I like how the build script is super easy to write now that all the heavy lifting has been hidden by the bazel build rules.

You now only need to do:

bazel run //tests/hello_world:emu

to see it run. Bazel will set everything up for you, build and run the script.

Details of that here, but now note how easy it is to write a build script which deploys a classic “hello world” in an emulator:

load("//build:sdcc.bzl", "sdcc_z180_c_binary", "sdcc_z180_cpm_emu_run")
load("//build/tim011-image:rules.bzl", "tim011_disk_image")
load("//build:macros.bzl", "tim011_emu_run")  # Probably needs reshuffling.

# This builds a Z180 C binary (a .COM file).
sdcc_z180_c_binary(
    name = "hw",
    srcs = ["hello_world.c"],
)

# This takes `base_image` and adds `HW.COM` to it.
tim011_disk_image(
    name = "img",
    base_image = "@mame_docker//:TIM011-Kit.img",
    binaries = [ ":hw" ],
)

# This runs the emulator with the built image, and starts the program "hw".
tim011_emu_run(name="emu", image=":img", program="hw")

The target sdcc_z180_c_binary builds a CP/M executable (named hw.com in this case). You can run only this step by using bazel build //tests/hello_world:hw.

The target tim011_disk_image makes a disk image from base_image (which is a TIM-011 bootable floppy), and adds the binary from the target :hw into the image. You can run this step by bazel build //tests/hello_world:img. It will of course rebuild :hw if needed before it builds the image.

The target tim011_emu_run creates a runnable target that boots a MAME TIM-011 emulator with the image :img and runs the program hw when it starts. You can run this step by bazel run //tests/hello_world:emu. It will of course rebuild the image and the binary if needed before it starts. So it’s very easy to run.