Pak It In
Like many machines of it's era (e.g. the Atari 2600), the CoCo had the option of using software distributed on ROM cartridges. The clever marketing folks at Tandy marketed this as "Program Pak" software... In any case, there are advantages to this software format. So, it might be nice to distribute compiled C programs the same way.
Relocating the compiled code to the ROM cartridge address space is the obvious first step. An added twist is the question of where to put the variables. Obviously, storing "variables" in ROM is of limited value. Luckily, the Dunfield library already provides for allocating variables in a different address range from where the code resides. Yet another variation of the startup code allows for selecting this configuration.
Many programs require the use of interrupts for proper operation. But, handling interrupts requires machine-specific accommodations that aren't part of the standard C language. Many compilers provide mechanisms for implementing interrupt handlers in C, and Micro-C is no exception. Unfortunately, the default mechanism provided with the Micro-C package generates code to hook the 6809's interrupt vectors in a ROM image. That is fine for use in an embedded system, but it won't work with the CoCo.
The CoCo ROMs redirect the interrupt vectors through a secondary set of vectors in RAM. Using the stock Micro-C interrupt implementation as a guide for interfacing with the compiled code, I implemented a CoCo-compatible version. My implementation uses a macro to output some inline assembly code in order to establish some code labels and to provide a 'trampoline' function. The trampoline function calls the C interrupt handler and then uses an RTI instruction to resume normal operation of the CPU. I also added some macros to make it easier to point the secondary interrupt vectors at the appropriate handlers in the C code.
One of the few timing sources on the CoCo is the ~60 Hz Vertical Sync (a.k.a. "Vsync") interrupt. With the code described above I was able to build a simple clock program that keeps time by counting Vsync interrupts. I also used an inline assembly macro to provide access to the SYNC instruction. This allowed me to properly time a colorful border animation for the clock -- the border is timed to complete a loop in approximately 1 second. Just for fun, I compiled the clock to run in the emulator as a ROM image. Since I didn't bother to burn a physical ROM, I also re-compiled the clock as a BIN file to load through the cassette interface on a real CoCo.
If you experiment with running my clock demo, you will find that the CoCo isn't really a very good time keeper. Keeping time by dead reckoning with an almost-but-not-quite 60 Hz timing source doesn't compete with the accuracy of a Swiss watch! I toyed with a few drift compensation strategies, but so far all I've done is prove that programming the CoCo in C is every bit as much fun as it is to program one in BASIC or assembly... :-)
Anyway, I guess that is enough for now. Only a few more days remain for the Summer 2013 Retrochallenge event. I hope to make the most of them, but I suspect that in any case I will be working on this project well past the end of the competition. Either way, I hope you will stay tuned!