Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(3 edits)

I had the same problem. Nuclear on Discord linked me to his timer code: https://github.com/jtsiomb/termtris/blob/master/src/dos/timer.asm

So in short, it doesn't seem to be possible (without hacking the OBJ) to make an interrupt function in C using Open Watcom when linking a COM.

Aggravating. CC65 has similar forced diversions into 6502 ASM, but CC65 is a glorified assembler macro. (Which does make it lightning-fast.) Watcom is old enough that this was relevant and Open Watcom is active enough that bugs still get fixed, and here it is tripping over itself. 

... nevermind, I solved it.

INT 21h will accept a normal function name in DX, for AX=0x251C (set interrupt vector 0x1C). The function will crash. But you can set it, and it will run. Once. Even _asm{ iret } won't return properly. The problem is, interrupts only push / pop the bare minimum of state. A function takes more setup and leaves a different stack.

But you can pad the function with _asm{ nop nop nop ... } and jump somewhere in the middle of those. Eight seems to work fine and I have no reason to push for fewer. The bare minimum presumably differs with the complexity of the function itself. So in the interest of doing things as sensibly as this jank allows - I wrote a wrapper function that only calls play_music normally and then does _asm{ iret }.

TLDR:

AX = 0x251C, DX = your_function_wrapper, DX += 8, INT 21h / int86 0x21. DS probably has to be zero as well.

void your_function_wrapper() {

_asm{ nop (8x, each one goes on a new line) }

your_function(); 

_asm{ iret }

}

Naturally this doesn't work in 86box. It runs - but it's audibly not running correctly. Back to tweaking and guesswork.

Found another way to do it, with one block of inline ASM tricking the processor into giving up the Instruction Pointer (because apparently Intel thinks it's supposed to be a secret!) and pointing earlier in the block of ASM to some custom code that definitely has no function / subroutine / procedure hang-ups. 86box don't care. 86box just does not like my sound function... when it is called by a COM file. An EXE works fine. So, screw it, this compo's getting a COM version specific to DosBox-X.