crazii / SBEMU

legacy sound blaster emulation for DOS
GNU General Public License v2.0
626 stars 33 forks source link

Yamaha YMF724/YMF744/YMF754 (DS-XG) driver with hardware FM/MPU-401 port remapping #81

Closed jiyunomegami closed 9 months ago

crazii commented 10 months ago

It's really great! please wait while I have a simple review.

crazii commented 10 months ago

Thanks for your great work! There're some minor suggestions and please confirm whether you like to change them. if you're not suitable to do it, will you agree that I slightly modify it after merge?

jiyunomegami commented 9 months ago

Please let me know your suggestions. There are some other changes that I made, related to the other Linux drivers, so it may be best if I do it.

crazii commented 9 months ago

Please let me know your suggestions.

I added some review comments on your change, can you check it?

EDIT: it's not related to linux drivers but to main_hw_fmport.

jiyunomegami commented 9 months ago

I looked all over but I can't find your comments. Please tell me where/how to view them.

crazii commented 9 months ago

I looked all over but I can't find your comments. Please tell me where/how to view them.

Sorry :), I forget submitting the reviews, now you can see it.

crazii commented 9 months ago

BTW are you located in Japan? I guessed by your id, if you are, I think we share a similar time zone which is convenient for both of us :).

jiyunomegami commented 9 months ago

Yes, Japan. I had some free time to work on this over the new year holidays (around Jan. 1st here.) I see your comments now, will respond later.

I have a question: The Trident 4D wave card cannot use DMA addresses above 0x40000000 (over 30 bits.) For example, I saw that the address gotten from pds_xms_alloc was 0xD97DD000. With that address, all you get is noise. When I use himemx /MAX=32768 I got a lower address 0x00511000, and proper sound.

Is there a way to get a lower address without limiting it with himemx options etc? I know that the Yamaha DSDMA has problems on modern systems if you don't use /MAX=32768 so this might be a related issue.

crazii commented 9 months ago

I remember there's a himemex2 wich allocates memory from low address. It comes with himemex in the original release, can you check that?

jiyunomegami commented 9 months ago

Thanks. I do get lower addresses with himemx2. I was using a 4GB stick of RAM. Now with 1GB I don't get anything over 0x40000000.

On this machine it is possible to allocate multiple times until you get a good address. I don't know if the BIOS has anything to do with it.

with over 4GB of RAM it goes something like this: DMA buffer physical address: D9821000 retrying DMA buffer physical address: 00111000 retrying DMA buffer physical address: 2022C000 retrying DMA buffer physical address: 42800000 retrying DMA buffer physical address: D9825000 retrying DMA buffer physical address: 00115000 retrying DMA buffer physical address: 20230000 retrying DMA buffer physical address: 42804000 retrying DMA buffer physical address: D9829000 retrying DMA buffer physical address: 00119000 retrying DMA buffer physical address: 20234000 retrying DMA buffer physical address: 42808000 retrying DMA buffer physical address: D982D000 retrying DMA buffer physical address: 0011D000 retrying DMA buffer physical address: 20238000 retrying DMA buffer physical address: 4280C000 retrying DMA buffer physical address: D9831000 retrying DMA buffer physical address: 00121000 retrying DMA buffer physical address: 2023C000 retrying DMA buffer physical address: 42810000

jiyunomegami commented 9 months ago

For the retry logic, I had to add MDma_alloc_cardmem_noexit, since MDma_alloc_cardmem calls exit when the allocation fails. Is there a reason for that? Can we just remove the exit call and have it return NULL?

crazii commented 9 months ago

Have you freed the previously allocated memory before retry? If not, then it will finally get more lower, but will leak/waste memories. If yes, I don't know why it behaves that way, it's weird. you might read the readme of himemex to know more about its allocation strategy.

The original routine assume that if one allocation failed, there's something wrong with memory allocation or not enough memory, so it simply exists.

I think you can return NULL but for other drivers it sill need exist from outside because the program is unable to run. or you can add one address limit parameter, somthing like MDma_alloc_cardmem_with_base_limit which performs the retry in it, and exit if retry failed, and MDma_alloc_cardmem calls to MDma_alloc_cardmem_with_base_limit with a max limit of 0xFFFFFFFF.

jiyunomegami commented 9 months ago

OK. I will add a new function. I think it is OK to simply add a function that returns NULL on failure, since that is what the Linux drivers expect. You can't free the allocated memory until you get a good address. Since the addresses of freed memory get reused. When testing how many allocations are possible, I could only allocate 40-50 times until it failed. I was only allocating 1 page (4096 bytes) at a time so I guess it is some limitation of XMS.

crazii commented 9 months ago

You can't free the allocated memory until you get a good address. Since the addresses of freed memory get reused.

Agreed. By the way of the retry, the memory cannot be freed before you get a valid address, but it will better to free them all after you get one. BTW you can allocate large blocks in multiple pages if the base limit is far slow from returned, anyway the retry logic is under your control and the retry functions is only used by Trident for now ( might be needed by more cards, let's wait and see)