Allegro.cc - Online Community
Post Reply

Allegro.cc Forums » Allegro Development » Allegro 4.2.3.1 (Dos) install_timer() causes crash

rss feed Print
Allegro 4.2.3.1 (Dos) install_timer() causes crash
megatron-uk
Member #17,010
February 2019

Using the last native Allegro/DOS release to write a port of my cross platform RPG game engine, and everything has worked well so far - blits to/from ram to vram, setting a custom VGA palette, detecting available mode-X/VESA modes, my bitmap based text printing library used on the other targets etc. All really slick and not a great deal of effort to go 'back to' after using SDL for some of the other targets.

I'm now at the point of swapping out the input routines from the other platforms to those of Allegro. That means install_timer(), install_mouse() and friends.

However, as soon as I call install_timer() the binary crashes.

My input initialisation routine looks like this:

int input_Init(void){
	int has_timer = 0;
	int has_mouse = 0;
	int has_joystick = 0;
		
	draw_LoadText("System timer...");

        // Crashes here!!!
	if (install_timer() == 0){
		has_timer = 1;	
		draw_LoadBar(-1);
	} else {
		screen_Exit();
		printf("Error, Unable to setup Allegro system timers for input devices!\n");
		return -1;
	}

	draw_LoadText("Mouse...");
	if (install_mouse() >= 0){
		has_mouse = 1;
	}
	draw_LoadBar(-1);

	draw_LoadText("Joystick...");
	if (install_joystick(JOY_TYPE_AUTODETECT) == 0){
		has_joystick = 1;	
	}
	draw_LoadBar(-1);
	
	draw_LoadText("Inputs configured");
	draw_ProgressIcon(TILE_CONTROLS);
	return OK;
}

If I comment out that one line and replace it with something that evaluates to true instead, then the code continues executing and the mouse and joystick routines return sane values.
This occurs both within Dosbox, as well as on real Dos hardware devices (a 386 and a P166).
I have not deliberately initialised any Allegro timers elsewhere in my code that I am aware of, only a allegro_init() at the very beginning.

I'm cross compiling using Open Watcom (2.0 beta Nov 24) on Linux. I wasn't able to get the Allegro libraries to build from source (does it work any more?) so I used the pre-built library from http://matejhorvat.si/en/dos/allegwat/.
Compile files are: CFLAGS = -3s -ox -d0 -mf -bt=dos -j -s -q -zq -dTARGET_DOS -dDEBUG

Here's what it looks like when it crashes: https://www.youtube.com/watch?v=INYKW50ZS40

Here's what it looks like with the install_timer() line commented out: https://www.youtube.com/watch?v=nw-UY8WWjHU

On Dosbox, the version with install_timer() terminates with the following error:

DOSBox version 0.74-3
Copyright 2002-2019 DOSBox Team, published under GNU GPL.
---
CONFIG:Loading primary settings from config file ../etc/dosbox-386-4mb-sb16.conf
MIXER:Got different values from SDL: freq 44100, blocksize 512
ALSA:Client initialised [128:0]
MIDI:Opened device:alsa
terminate called after throwing an instance of 'char*'
Aborted

===========

Following up myself, a simple test harness for install_timer() shows that it does install in a minimal test case:

int main(){
	int i;
	
	printf("Starting allegro\n");
	i = allegro_init(SYSTEM_AUTODETECT, &errno, NULL);
	if (i != 0){
		printf("Error: Allegro library did not install!\n");
		return(-1);	
	} else {
		printf("Ok!\n");	
	}
	
	printf("Installing timer\n");
	if (install_timer() == 0){
		printf("Ok!\n");
	} else {
		printf("Error, Unable to setup Allegro system timers for input devices!\n");
		return -1;
	}
	return 0;
}

... So there exists something elsewhere in the code that is messing up the call to install_timer().

Any ideas what sort of other functions would cause a system crash/reboot at the point of installing the Allegro timers?

Dizzy Egg
Member #10,824
March 2009
avatar

I think you need to install timer directly after initialising allegro, definitely before doing any drawing routines...

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

megatron-uk
Member #17,010
February 2019

Changed my main() to do this first:

int main(void){
	
	char c = 0;
	unsigned char main_exit = 0;

	printf("%s starting...\n", ENGINE_NAME);
	
	printf("-- Loading Allegro ");
	c = install_allegro(SYSTEM_AUTODETECT, &errno, NULL);
	if (c != 0){
		printf("Error: Allegro library did not install!\n");
		return(MAIN_SCREEN_FAILURE);	
	} else {
		printf("Ok!\n");	
	}
	c = install_timer();

        while(1){};

       // Snip... all of the screen init comes next, then the graphical
       // loading screen, input initialisation, like this....
       //c = screen_Init();
       //if (c != SCREEN_OK) handle error......
       //audio_Init()
       //if (c != AUDIO_OK) handle error......
       //input_Init()

... and now it terminates before even doing the screen initialisation. In fact, even with that infinite loop as the next line after install_timer(), the binary still terminates; despite never even getting to anything that should remotely touch Allegro internals.

In desperation I've tried changing the link type from the dos32 extender to dos4gw (-ldos4gw rather than -lstub32x), but that hasn't made any difference.

The difference in behaviour to that standalone timer example I posted above must mean that there is something else being linked in my application that is messing with the install_timer() behaviour, since the test binary does not terminate prematurely.

What that 'other' thing is which is causing this behaviour I have no idea. I did have another audio library (https://github.com/volkertb/JUDAS) linked in, which I though may have installed its own (incompatible) timers/interrupts, but I've stripped out any function calls against it and removed the library from the link stage for now, so I know it's not that.

-------

Edit: Made another video of install_timer() added at the very start of my main() function, just after install_allegro. I show the code compiling without error and running normally. Then I uncomment the line which has install_timer(), build/run it again and view the abnormal termination:

https://www.youtube.com/watch?v=fy3CDoJufqQ

I can't put the line any higher - there's only one or two printf statements before I call install_allegro!

Does anyone have a recipe for building Allegro 4 on (a modern) Linux for a DOS target? It looks like I may have to resort to building it from source and trying to debug install_timer() to understand why it is blowing up.

--------

Edit #2: It's OpenWatcom.

I've rebuild the Allegro 4.2.3.1 library (with the -fgnu89-inline option in makefile.dj, and added the two missing symbols 'int ds' and 'int saved_ds' in vbeaf.c) using a fresh install of GCC 12 from https://github.com/andrewwutw/build-djgpp/releases... and install_timer() no longer terminates the application.

I've got some bugs to hunt down, as there are other things that need fixing for the djgpp cross compiler to work nicely (and it uses cwsdpmi, which isn't nearly as nice as dos32a.exe), but I think this puts to rest the question about what was wrong - clearly the Watcom runtime is doing something to the machine state that the Allegro timer code does not agree with.

Post Reply
Go to: