C68 & detecting vsync

Anything QL Software or Programming Related.
User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: C68 & detecting vsync

Post by mk79 »

The value is increased on every V-Sync, so the wait should be the same (except a little bit later as the OS handlers will first execute normally)


megatron-uk
ROM Dongle
Posts: 10
Joined: Tue Jan 04, 2022 9:25 am

Re: C68 & detecting vsync

Post by megatron-uk »

Actually, I'm still seeing some odd behaviour with this poll/wait routine... but I don't know if it's an interaction with sQLux that is causing it.

With the poll/wait routine in, I observe that each time I call it, the delay gets shorter and shorter relative to the same wait value I pass it, an initial value of 10 - which is a noticeable delay at first, ultimately becomes almost imperceptible after being called more than 5 or 6 times.

Also, the poll/wait routine appears to be causing a memory leak - my free memory pool available to malloc from decreases by (approximately) 512 bytes after each call as I suspect there is a new job being created on each call.

Should there be a call to remove the poll/wait routine, or somehow reinstantiate the existing job?

The implementation is a very basic one:

Code: Select all

void screen_Vsync(unsigned char wait){
	volatile unsigned int c = 0;
	poll_init(&c);
	while (c < wait){
	}
}
For my menu-item-animation code, it is used as follows in an alternating pattern of white background + black text, and then black background with a selected fill:

Code: Select all

draw_Box(screen, x1, y1, w, h, 0, PIXEL_WHITE, PIXEL_WHITE, MODE_PIXEL_SET);
	draw_String(screen, col, y, max_chars, 1, 0, screen->font_8x8, PIXEL_BLACK, c, MODE_PIXEL_XOR);
	screen_Vsync(10);
	for (i = 0; i < 4; i++){
		// Invert text and highlight
		draw_Box(screen, x1, y1, w, h, 0, PIXEL_BLACK, PIXEL_BLACK, MODE_PIXEL_SET);
		draw_String(screen, col, y, max_chars, 1, 0, screen->font_8x8, fill, c, MODE_PIXEL_SET);
		screen_Vsync(5);
		// Normal text
		draw_Box(screen, x1, y1, w, h, 0, PIXEL_WHITE, PIXEL_WHITE, MODE_PIXEL_SET);
		draw_String(screen, col, y, max_chars, 1, 0, screen->font_8x8, PIXEL_BLACK, c, MODE_PIXEL_XOR);
		screen_Vsync(5);
	}
... it would of course be more elegant to simply NOT the bytes in the bounding box formed by the x/y coordinates, but for the moment I'm just blanking out and re-printing.


User avatar
tofro
Font of All Knowledge
Posts: 2702
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: C68 & detecting vsync

Post by tofro »

megatron-uk wrote:Actually, I'm still seeing some odd behaviour with this poll/wait routine... but I don't know if it's an interaction with sQLux that is causing it.

With the poll/wait routine in, I observe that each time I call it, the delay gets shorter and shorter relative to the same wait value I pass it, an initial value of 10 - which is a noticeable delay at first, ultimately becomes almost imperceptible after being called more than 5 or 6 times.

Also, the poll/wait routine appears to be causing a memory leak - my free memory pool available to malloc from decreases by (approximately) 512 bytes after each call as I suspect there is a new job being created on each call.

Should there be a call to remove the poll/wait routine, or somehow reinstantiate the existing job?

The implementation is a very basic one:

Code: Select all

void screen_Vsync(unsigned char wait){
	volatile unsigned int c = 0;
	poll_init(&c);
	while (c < wait){
	}
}
Don't call poll_init on every cycle. It will instantiate a new polling interrupt routine every time (that's the reason for both your memory leak and the slowdown).

Call poll_init only once, then re-set the counter c to zero when you wait.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
megatron-uk
ROM Dongle
Posts: 10
Joined: Tue Jan 04, 2022 9:25 am

Re: C68 & detecting vsync

Post by megatron-uk »

Okay, okay, got it. So I need to put the counter variable somewhere in one of my global screen structures which is where any of the timer-sensitive delay loops will be running.

I'm afraid I don't follow 90+% of the assembly listed so I do very much appreciate all of the assistance - the last time I did any assembler at all was some 25+ years ago in a 6 week block of my undergraduate degree. It has been a long time since then... :D


megatron-uk
ROM Dongle
Posts: 10
Joined: Tue Jan 04, 2022 9:25 am

Re: C68 & detecting vsync

Post by megatron-uk »

tofro wrote:
Don't call poll_init on every cycle. It will instantiate a new polling interrupt routine every time (that's the reason for both your memory leak and the slowdown).

Call poll_init only once, then re-set the counter c to zero when you wait.
Oh that works brilliantly, thank you!


neozeed
ROM Dongle
Posts: 15
Joined: Thu Jan 06, 2022 7:54 am

Re: C68 & detecting vsync

Post by neozeed »

mk79 wrote: Sat Feb 12, 2022 7:40 pm Looks nice.
megatron-uk wrote:However, the game is a bit flat looking; I haven't yet got any animation, loading icons, etc... as I'm finding it difficult to find a method to synchronise / wait on display refresh - the C68 standard library only appears to have a second-granularity sleep() and nothing else that would help.
You can do the same thing as sleep (calling mt_susjb) to get down to 20ms granularity.
I see that there is some documentation on https://www.chibiakumas.com/68000/sinclairql.php for reading the state of the vsync interrupt, but I am hampered by the fact that C68 (at least in the xtc68 incarnation) doesn't appear to support inline assembly.
You will never read anything but 0 as these will always be handled by the appropriate interrupt handlers. For your bit-twiddling solution you would need to disable interrupts and it will never work on advanced emulators like QPC.

The clean thing to do is to link in a polled interrupt service routine and for example increase an integer in it that you can busy-wait on in the main job. This is a bit tricky to do, especially as the routine must be removed when the job is killed, otherwise the system will crash. Explaining the details that must be observed is too time consuming, so I wrote some example code you can try out.
Thanks so much for that sample code! I don't think I'd ever have any hope on getting a simple clock ISR going!

THANKS!! :D


Post Reply