lgblgblgb / xemu

Emulations (running on Linux/Unix/Windows/macOS, utilizing SDL2) of some - mainly - 8 bit machines, including the Commodore LCD, Commodore 65, and the MEGA65 as well.
https://github.com/lgblgblgb/xemu/wiki
GNU General Public License v2.0
201 stars 31 forks source link

MEGA65: new DMA MB-crossing policy ideas to be implemented in Xemu #410

Open lgblgblgb opened 2 weeks ago

lgblgblgb commented 2 weeks ago

This issue is meant to be a reminder for myself, if the idea takes in effect in mega65-core. More information: https://github.com/MEGA65/mega65-core/issues/826

In nutshell: a new proposal to allow crossing megabyte boundary by the DMA with allowing to modify the MB "slice" during a DMA session if it's needed. It would be problematic b/c the non-crossing policy is intentional (see the issue above) however with an enhanced mode DMA option it may have been enabled.

I don't plan to implement this till it's really accepted in the mega65-core.

It will be a pain in the rear end, since the basic "fabric" of Xemu's DMA emulation is based on the fact that MBYTE is fixed and the src/dst counter changes (within the mbyte "slice"), so it will be slower emulation etc, but hey, that's life ...

Update

It seems the solution will be a global setting to allow MB crossing, ~so no DMA enhanced mode option~ (there is, just there is the global thing too!). Probably a bit in $D703. Questions remained:

It seems, hypervisor mode implies not using wrapping ever:

if (reg_dmagic_cross_mb_boundaries='0' and reg_dmagic_no_default_mb_wrap='0') or hypervisor_mode='1' then
    dmagic_dest_addr(35 downto 28) <= dmagic_dest_addr(35 downto 28); -- do not update MB part of address
end if;

mega65-core PR: https://github.com/MEGA65/mega65-core/pull/830

Emulation

As for now, Xemu implementation is delayed till it's usable in mega65-core, and the details become clear. Probably it means refactoring the DMA emulation code, as it has the fundamental design to have a "base" address and only a changing "within-MB" part. Also, 32 bit is not enough then, since I use fixed point arithmetic (8 bit for fractional step), thus it would need 28 bit + 8 bit = 36 bits. Either I have to migrate using 64 bit integer, or another solution should be introduced.

ki-bo commented 2 weeks ago

Sorry if my proposal is causing you pain - even just thinking of it in advance ;-) We are still in discussion about it. On the other hand, if you want to have ATTIC RAM as a large HEAP of data or load large amounts of raw data there, you may quickly end up with situations where data to be accessed happens to land crossing such a MB boundary. The hardware limitation at the moment is not due to a complex implementation, but just as a HYPPO safety feature.

lgblgblgb commented 2 weeks ago

Sorry if my proposal is causing you pain - even just thinking of it in advance ;-) We are still in discussion about it. On the other hand, if you want to have ATTIC RAM as a large HEAP of data or load large amounts of raw data there, you may quickly end up with situations where data to be accessed happens to land crossing such a MB boundary. The hardware limitation at the moment is due to a complex implementation, but just as a HYPPO safety feature.

:D No worries, I can be grumpy about the emulation headaches (basically all the time ... - that's my style we can say), but that shouldn't dictate what is good for the hardware platform ;)

lgblgblgb commented 5 days ago

@ki-bo One thing is not crystal clear for me: if MB-crossing is enabled globally (D703.1) then it also applies to non-MEGA65-enhanced DMA jobs like for both of F011A and F011B style? Surely the option-enabled ensures it's a MEGA65 enhanced DMA, since then we have the options at all, but what's about the "plain" F011A and F011B DMA jobs?

ki-bo commented 5 days ago

The current implementation is like the A/B global override flag in $D703.0 and applies to all jobs outside HYPPO.

But I don't believe this is relevant, as the only use-case for this feature is ATTIC RAM access anyway. Without enhanced job options, you won't be able to hit a meaningful MB boundary. The global option is available so the developer of an application or game can initialize this globally and does not need to remember/repeat this option again and again. Same for the A/B DMA type: you can select that on each job again, or you just configure it once via $D703.0.