Great project! Kudos for figuring out all that stuff on your own. Assuming you are actually reading these comments, a few suggestions:

* C compilers that can target 16 bit x86 usually have support for "far pointers", which are 32 bit wide pointers consisting of both a 16 bit segment and a 16 bit offset. You should be able to use that instead of your assembly wrappers. This allows you to directly access screen memory in C, i.e. letting the compiler do the job of setting up the segment registers, which also has the great benefit of not having to push, write, and pop ES for every byte (if you copy a block into screen memory for example, the compiler only needs to set up the destination register once).

* The IVT is correspondingly also a list of FAR pointers. It's a common 16 bit x86 concept. The CPU knows about them, they are also more generally used for far jumps and far calls.

* As others have said, just pick one of the many, many available text mode font ROMs.

* I'm curious how compatible that AMD Elan is to actual PCs. Probably a lot, since by that time PCs were kind of the x86 standard, though not necessarily. The earlier 80186 with its integrated peripherals (interrupt controller etc.) was very incompatible, for example. Shouldn't impede your project, just dictates how easily you can run DOS programs overall.

I'm curious how compatible that AMD Elan is to actual PCs.

It's 100% PC/AT compatible, a "PC-on-a-chip" type SoC.