Reading List

The Selfish Gene
The Psychopath Test: A Journey Through the Madness Industry
Bad Science
The Feynman Lectures on Physics
The Theory of Everything: The Origin and Fate of the Universe


ifknot's favorite books »

Sunday, 19 April 2026

DOSBox_joker.png CGA mode 6 "hi res"

Getting Zed and Clangd to Be Useful for the Retro Programmer

My editor of choice is Zed. It is fast, modern and minimal. My compiler is Open Watcom (which is a modernised Watcom) ancient and idiosyncratic but correct for the IBM XT target I am writing for. The problem is that clangd, the language server that Zed uses for C and C++ code, has opinions about my code - strong opinions.

As I have argued elsewhere, modern language servers and retro compilers are not natural bedfellows. Clangd expects C17, not 8086 assembly with __fastcall calling conventions and inline __asm blocks. Open Watcom accepts all of that happily, because it was built for the retro target, but clangd was not. The two do not speak the same dialect, and the result, without configuration, is an editor full of red squiggly underlines under perfectly valid code.

Consider then, a typical function from my codebase:

void __fastcall cga_hi_res_plot(cga_coord_t x, cga_coord_t y, cga_colour_t colour) {
   __asm {
      .8086
       mov     ax, x
       
       etc...
  }
}

Clangd flags __fastcall as an unsupported calling convention. It flags __asm as unknown syntax. It has no idea what .8086 means. The code compiles without complaint under Watcom and the XT runs it beautifully, but my editor thinks I am writing nonsense.

The Solution a .clangd File

The most reduced form of a working configuration for this problem is a .clangd yaml file in the project root directory that Zed will honour:

CompileFlags:
Add: [-xc, -Wno-ignored-attributes, -fms-extensions]
Remove: [-std=c99]

The -xc flag forces clangd to treat the code as C rather than Objective-C++, which for reasons I do not fully understand is sometimes the default. The -Wno-ignored-attributes flag suppresses the warning about __fastcall being unsupported, which is a lie but a lie we can live with. The -fms-extensions flag embraces the Microsoft and Watcom dialect, which helps with the rest of the weirdness. Removing -std=c99 prevents clangd from insisting on a language standard that my code does not fully follow because neither does Watcom.

The Include That Was Not Unused

A second problem emerged after the squiggles were gone. I have a lookup table for CGA row offsets:

#include "cga_lookup_table_y.h"   // clangd says: unused and paints it with yellow squiggles

The header is used extensively, but it is used inside __asm blocks. Clangd cannot see past the veil of inline assembly, so it flags the include as dead code. This is a false positive, but it is a persistent one.

The solution is a pragma from the Include-What-You-Use (IWYU) tooling:

#include "cga_lookup_table_y.h"   // IWYU pragma: keep

This communicates to the analyser that the inclusion is intentional, even if the static analysis cannot observe its usage. The warning disappears, the header remains, and the code continues to work.

Conclusion

So, fellow retro programmers, you can have best of both worlds. With Zed and .clangd configuration you can transform a hostile language server into a useful assistant. The defining properties of such a configuration are that it accepts non-standard calling conventions with -Wno-ignored-attributes, accepts the Watcom dialect with -fms-extensions, preserves includes hidden behind assembly with // IWYU pragma: keep, and - most importantly - lets you keep code completion.

Sunday, 27 July 2025

Applying Design by Contract to C

                   Exploring a practical approach to bringing DbC principles to a language that has a bad reputation for safety.

Synopsis

Design by contract was first coined by Bertrand Meyer in connection with the Eiffel programming language, and it was described in various articles starting in 1986, as well as in his book "Object-Oriented Software Construction" published in 1988 and 1997. The concept emphasizes defining formal interface specifications for software components, akin to business contracts. 

My background reading suggests that Design by Contract (DbC) has never been mainstream and, even

Saturday, 17 October 2020

Reading dumb data into the C++ heterogeneous data_frame

 

Ingest some CSV

Last month I presented an R-ish data_frame class as a small side project, this month I present a C++ equivalent of the R read.csv()function to import data into a data_frame class.

Ongoing development is at the github repo: https://github.com/ifknot/rpp

To recap the motivation for the C++ heterogenous  data_frame class was two-fold:
  1. Runtime handling of dumb data whose format, types, and fields are unknown.
  2. Enable data science skill transfer from the R functional programming environment into C++.
The motivation for the read_csv()function remains the same as that for heterogenous the  data_frame class:

"I want to be able to do the same sort of thing that I do R, but in C++".

Which, this time around, means that I want to be able to use one of the easiest and most reliable ways of getting data in - text files.

In particular CSV (comma-separated values) files. The CSV file format uses commas to separate the different elements in a line, and each line of data is in its own line in the text file, which makes CSV files ideal for representing tabular data - i.e. the  data_frame class.

Saturday, 5 September 2020

A heterogeneous data frame in C++

 

Organise your data the R way

NEW! - more stuff and in a github repo - https://github.com/ifknot/data_frame

I like R for statistics. The variables in R are lexically scoped and dynamically typed. 

I like C++ for just about everything else. C++ is a strongly typed language and it is also statically-typed; every object has a type and that type never changes.

I want to do some simple statistics in C++ but I can't imagine doing that without a heterogenous Data Frame.

I want to be able to do what I do in R - desiderata:


But in C++ - ipsa:


It does this (unlike R in C++, indexing begins from 0)


Here's how...

Wednesday, 15 July 2020

PiDP11 211BSD Jove cursor key bindings




JOVE - How do you keymap VT100 arrow keys?

I found the answer in a 1991 comp.editors Google Group or rather 3 answers courtesy of  Alan Coopersmith (Open Computing Facility, Berkley) quote...

There are 3 basic solutions (all of which are commands put in your
.joverc file):
1. Upgrade to version 4.14 (I was told 4.9 really means 4.09) and use:
>       make-keymap vt100-map
>       bind-keymap-to-key vt100-map ^[[

>       bind-to-key next-line ^[[B
>       bind-to-key previous-line ^[[A
>       bind-to-key forward-character ^[[C
>       bind-to-key backward-character ^[[D
2. Use this (not sure which version):
             bind-to-key prefix-3 ^[[

             bind-to-key next-line ^[[B
             bind-to-key previous-line ^[[A
             bind-to-key forward-character ^[[C
        bind-to-key backward-character ^[[D
3. Stay with version 4.9 and use:
        bind-to-key ansi-codes ^[[
        bind-to-key ansi-codes ^[O
I will use #3 since it doesn't require bothering the overworked/unpaid
OCF staff to install a new version.  It is also the simplest, but only
works with vt100/ANSI term types.  If you want to do assign keys on a
vt220 or a Sun or anything else that doesn't use the vt100 key codes, you
need a version past 4.9.  (To find out what version you have type M-X
version).
I used solution 3. and that worked just fine.


PiDP11 211BSD upgrade to patch level 469 (Chase Covello 2019)


Upgrade 2.11BSD to patch level 469 - Chase Covello (2019) github

Chase Covello's 2.11BSD patch 469 adds a number of features not least of which is the EMAC-like editor jove as a more humane editor than vi.

Display high-resolution graphics with the Tektronix 4010 terminal emulator

Log in as user tektronix. The directories under /home/tektronix/ contain example programs and plot files for use with Rene Richarz’ Tektronix 4010 graphics terminal emulator. [manual]

Saturday, 11 July 2020

PiDP 11 ~/php.sh returns 0 Version GLIBC_2.28 not found



The latest version of smh for the PiDP11 requires glibc 2.8 unfortunately Raspbian stretch has version 2.4 and so your updated install of smh wil not work.

However, it is possible to update stretch to buster and this will solve the problem.

How to do this is a straight cut & paste from DDuck at
 https://www.domoticz.com/forum/viewtopic.php?t=30219

Let’s first update all the currently installed packages by running the following command.
CODE: SELECT ALL
sudo apt update
sudo apt dist-upgrade -y
Next, let’s go ahead and also update the Raspberry Pi’s firmware.
We can do that by running the command below on our Raspbian installation.
CODE: SELECT ALL
sudo rpi-update
Now that we have prepared our Raspbian Stretch installation, we can now start the process of moving to Buster.