XGM Driver issue

SGDK only sub forum

Moderator: Stef

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

XGM Driver issue

Post by Manveru » Fri Nov 16, 2018 10:12 pm

Hello mates.

I am trying to add current XGM driver to my code, but i can't make it work properly.
I copied the sound files keeping all the files unchanged, except some VDP functions replaced with the ones in my code.
I updated my VINT function to look like the one in SGDK in terms of audio and dma, and then i tried to play some sounds.
Playing fx PCM samples is ok at the 4 channels, and also music is fine playing fm and psg. The problem seems to be the PCM samples ni the music. I have tested it with a lot of audio, including samples and music in the XgmPlayer code.

First, the music sounds perfectly in any emulator (Blastem, Exodus and Fusion) except in Gens Kmod, where instead of the music samples, it can be heard just an annoying sound. When a friend tested it in the console, the roms keep black and quiet, no sound and frozen.
Possibly the buggy sound of Kmod can be a clue to discover why the console freezes, when accurate emulators like Blastem and Exodus seems to skip that issue.

Probably something bad happends in XGM load, that makes Kmod evil noise sounds and console to freeze. In Kmod, when i play a music with the sample noise, then if i play a fx sample in channel 1 it sounds perfectly and the noise is not heard while fx sample is running. So it seems not to be a problem of the channel... it is like the music plays the sample using FM6 like an FM, not like PCM (just a crazy theory :P)

I have tested booting the rom just with the basic stuff for playing a music track. I have tested a lot of different codes of console and Z80/Yamaha/Psg booting (including copy pasting SGDK boot), i have tested different GCC versions and different makefiles implementations, but the problem can not be solved.

I have not any idea of what can i do next, because i have tested tons of ways and my knowledge of the Yamaha and Z80 assembler is zero. I do not know if SGDK does something else to the XGM driver, or if XGM driver needs something else from SGDK at a low level that i can not see. Maybe at the Makefile it needs some special action i can not see... I do not know, i triend hundreds of things and i am now completely lost.

I hope Stef or someone else can help me. Thanks.
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: XGM Driver issue

Post by Stef » Sat Nov 17, 2018 12:32 pm

Hi Manveru,

From what you describe the problem will be complicated to sort out :-/
What surprise me is that accurate emulators are perfectly working while Gens KMod (which is not really accurate) give you troubles...
Also weirdly the PCM from music doesn't play while PCM from SFX are ok, so i'm wondering if you correctly replicated the XGM_playMusic(..) command where the sample table address is copied to Z80 RAM.
Did you try to do a minimal sample able to reproduce the problem ?
Just playing one music with 1 set SFX for instance...
Then you try to do exactly the same with SGDK (should be fast) and see if it replicates the problem both on Gens KMod and a real MD ?
If the SGDK sample works then yoy may gradually modify it to replicate your version (shortcutting the vint by your...) and see when the problem happen.

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Sat Nov 17, 2018 1:11 pm

Thanks for your answer Stef.

Yep, it is very weird that all the accurate emulators play the music perfectly, the Kmod can not play samples in music and console freezes before the music starts.

The last thing i tried is just loading the booting file (SGDK sega.s just with my vint function), then it jumps to main. There i added the code for just starting all VDP registers and run PSG_init and Z80_init, like you do in SGDK. Nothing more is run (no dma, tiles, palettes, sprites, no dynamic memory, no engines...). Then i enable the interrupts, play the music file and enters in an infinite loop of vints.

I found something very interesting this morning: when i move that main stuff into the beginning of the "load_game" function (the first function call in the regular main function), then the glitchy sample noise in music can be heard in Blastem too. Just by calling another function in main (no other stuff is made) provokes Blastem get glitchy too.
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: XGM Driver issue

Post by Stef » Sat Nov 17, 2018 2:08 pm

i guess replacing your vint method by the one in SGDK is enough to get things working correctly then ?

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Sat Nov 17, 2018 2:57 pm

I can not replace the Vint function with SGDK one because it uses a lot of stuff for DMA, tiles, fades... that i do not use.
My vint function is now reduced to 2 lines for those test:

Code: Select all

       vtimer++;
       if (VIntProcess & PROCESS_XGM_TASK)
            XGM_doVBlankProcess();
Of course i have tested different implementations, adding and removing lines, DMA with bus requesting... but all have the same result.
I also have tested loading the driver manually, manual sync, different speeds... but always the same result.

EDIT: i tried to remove PSG_init and Z80_init from the initialization, and the result is the same.
I have now the Sega.s from SGDK, just changing the vint with the above code. Then it jumps to Main with VDP register init (tested mine and SGDK initial VDP values). Nothing more initialized (no z80, psg, yamaha, joypads, no access to vram, cram or vsram, no dma...). Enable ints at 68k, enable vint at VDP and play music. That's all my code now
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: XGM Driver issue

Post by Stef » Sun Nov 18, 2018 8:13 pm

Can you do tests under Gens KMod emulator and take Z80 RAM shot (into a file) to compare your version versus a minimal 100% SGDK version (which work normally obviously). Analysis differences in Z80 RAM state may help in understanding the problem, otherwise i can't do really much from what you told me :-/

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Sun Nov 18, 2018 9:55 pm

I was doing what you told me about porting the code to the SGDK version step by step. Now i am fully using SGDK but i can not get it to work.

I got the 1.34 SGDK version, i added the global vars and path data, and then i created a folder with just a main.c file in src and i copied the samples and music in res xgmplayer folder. In the main file i just have this main function:

Code: Select all

#include "types.h"

#include "sys.h"
#include "vdp.h"
#include "z80_ctrl.h"
#include "xgm.h"
#include "sound.h"

#include "music.h"


int main(u16 hard)
{
    XGM_setPCM(64, pcm_loop, 57856);
    XGM_startPlayPCM(64, 15, SOUND_PCM_CH2);

    while(1)
    {
        VDP_waitVSync();
    }

    return 0;
}
But the codes remains inside the loop of the driver loading, an infinite loop awaiting for the driver to be ready.

Code: Select all

while(!Z80_isDriverReady())
	while(Z80_isBusTaken());
After some vints, the kmod starts to output a lot of warnings or errors. Of course, nothing can be listened...
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Mon Nov 19, 2018 11:10 am

A friend tested in his computer the last SGDK with the simple main sample playback and he got the same results, so i am happy to know it is not a problem of my computer or its configuration.

In kega fusion the sample can be heard, but in blastem, exodus, regen and kmod, no sound is listened.

Using kmod kdebug debugging, i can see the code remains trapped in the loop i wrote before. I keeps waiting for the driver to be ready, but it never happends. I remember i got the same infinite loop with my code in the early stages of my tests adding xgm, but i do not remember how i fixed it.

I compiled the xgm player folder and it works fine, i do not understand what happens with the sample.

This is a Z80 ram dump while in the infinite loop:
https://drive.google.com/file/d/1uzputN ... sp=sharing

And this is the one after KMod debugger start logging errors:
https://drive.google.com/file/d/1PhGuz5 ... sp=sharing
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Re: XGM Driver issue

Post by Chilly Willy » Mon Nov 19, 2018 2:26 pm

Code: Select all

while(!Z80_isDriverReady())
	while(Z80_isBusTaken());
You DO realize that Z80_isBusTaken() merely checks if the 68k has halted the Z80? That "while(Z80_isBusTaken());" either does nothing, or it hangs forever, depending on if the Z80 has been halted.

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Mon Nov 19, 2018 2:46 pm

Chilly Willy wrote:
Mon Nov 19, 2018 2:26 pm

Code: Select all

while(!Z80_isDriverReady())
	while(Z80_isBusTaken());
You DO realize that Z80_isBusTaken() merely checks if the 68k has halted the Z80? That "while(Z80_isBusTaken());" either does nothing, or it hangs forever, depending on if the Z80 has been halted.
Yes, that is the problem, the question is why that happens in my simple code and not when i compile xgmplayer.


EDIT: thanks to mate Paspallas, i realise removing -O3 from the makefile compiler arguments makes it works. I tried replacing -O3 with -O1, -O2 and -Ofast, and with all of them the rom fails. Just when i removed all -OX the sound can be heard.

I also did that to my original code, the one i was adding xgm to, and then the music sample sounds good.
Of course it is a big problem because without optimizations, any rom runs incredibly slow :?
Last edited by Manveru on Mon Nov 19, 2018 3:28 pm, edited 2 times in total.
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: XGM Driver issue

Post by Stef » Mon Nov 19, 2018 3:25 pm

Ohh.. again a compiler optimization issue, generally optimization issue are caused by missing "volatile" keyword on port access.
It also may be related to your "wait" loops. I observed for instance that in some situation the VDP_waitVSync() method may be optimized by the compiler so that the next line of code could be executed *before* the VInt actually occurs. In fact on real hardware, the VInt occurs right after the VBlank flag is set but it let you very few time so normally it doesn't create any troubles... still i preferred to add a new method VDP_waitVint() so you are sure the VInt actually occurred when this is not necessary the case with VDP_waitVSync() :p

Just to explain you that depending compiler optimization level, timing may make a wrong code to pass or not.
And definitely this loop taken alone :

Code: Select all

while(!Z80_isDriverReady())
	while(Z80_isBusTaken());
Can goes wrong. In SGDK i used it as i do know the bus is not taken here, and it was just to spent some cycles.
The thing is that it always worked for me whatever was the compiler optimization level but just to be safe I just modified the code on the repository to avoid "weird things" depending compiler optimization level.

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Mon Nov 19, 2018 3:30 pm

Stef wrote:
Mon Nov 19, 2018 3:25 pm
Ohh.. again a compiler optimization issue, generally optimization issue are caused by missing "volatile" keyword on port access.
It also may be related to your "wait" loops. I observed for instance that in some situation the VDP_waitVSync() method may be optimized by the compiler so that the next line of code could be executed *before* the VInt actually occurs. In fact on real hardware, the VInt occurs right after the VBlank flag is set but it let you very few time so normally it doesn't create any troubles... still i preferred to add a new method VDP_waitVint() so you are sure the VInt actually occured when this is not necessary the case with VDP_waitVSync() :p
Folowing Chilly Willy point of view, i think the optimizations removes some line where Z80 should be restored, reseted or whatever it needs.

For the Vints, what i do is to add a var controling if the main code ended in time and the code is ready for the vblank, and if the vblank ended in time to return to main and let the new frame to start.
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Re: XGM Driver issue

Post by Chilly Willy » Tue Nov 20, 2018 2:50 am

Any code that deals with hardware must use volatile pointers AND have memory barriers protecting it or you'll have issues depending on the optimization level. I ran into that early on with the 32X. In general, memory barriers aren't discussed on the net except for x86. So it can be difficult finding the info you need for a particular platform, in this case, 68000.

cero
Very interested
Posts: 338
Joined: Mon Nov 30, 2015 1:55 pm

Re: XGM Driver issue

Post by cero » Tue Nov 20, 2018 10:26 am

__sync_synchronize() seems to compile fine with my sgdk gcc.

Manveru
Very interested
Posts: 85
Joined: Wed Sep 05, 2012 3:30 pm

Re: XGM Driver issue

Post by Manveru » Tue Nov 20, 2018 12:32 pm

I had no idea about memory barriers. It is common not to find much info about 68k and gcc, and it is usually a problem. I hope Stef and the people like you who know about that stuff can improve SGDK and let us learn about that good behavior programing for the mega drive.
The man who moves a mountain begins by carrying away small stones. Confucius, 551-479 BC

Post Reply