MEGA65 / mega65-core

MEGA65 FPGA core
Other
240 stars 85 forks source link

Feature Request: Including an OPL3 FM sound chip in the MEGA65 #232

Open gardners opened 4 years ago

gardners commented 4 years ago

A number of people have asked about this. There is an open-source verilog implementation that we can make use of.

lgblgblgb commented 4 years ago

Can you tell me what is the exact mega65 "linear" address for the register selection (in case of PC + AdLib it would be 0x388, $DF40 on C64 + SFX sound expander cartridge) and register data (in case of PC + AdLib it would be 0x389, in case of C64 + SFX it would be $DF50)? I guess with OPL3 the situation can be a bit more complex maybe (I'm not sure) left/right channel or some reg addresses for both. I've written C64 player already in the past for the SFX cartridge. With minimal modifications, it would be suitable for testing, if I know the addresses I need to use (that's for OPL2 expanded SFX which is OPL1 by default, but anyway, OPL3 is OPL2 compatible, so it should work the same way). From the commit I can see the memory range assigned for the function, but I'm quite unsure the needed two ones exactly ... Thanks!

Btw, I meant this program by me:

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

UPDATE: or (just come into mind) the reason of having 256 byte reg range, that you have no register select / register data, but writing the given register in that 256 bytes long area would mean the same as selecting register and then access it on a real OPL chip?

gardners commented 4 years ago

Yes, all 256 registers are directly mapped at $FE000xx, so there is no select register. And this is lovely to discover you have a player, as I had been wondering how I was going to test this. Do you have the source for your player still, so that we can try modifying it for the address? Even if not, we can change the STA $DF4x to JSR somehwere that does the writes.

gardners commented 4 years ago

I could also look at doing some magic to allow the OPL2/3 to be mapped as though it were a C64 SFX cartridge...

gardners commented 4 years ago

More example software if we do provide SFX compatibility at: http://c64.xentax.com/index.php/fm-yam

lgblgblgb commented 4 years ago

Just to have a note here as well: I've updated my OPL player repository: there is now a mega65 version as well (which does direct mega65 compatible register addressing), also PRG files, to avoid compiling:

Of course, full source code (needs CA65) is available (GNU/GPL v3).

Project page (also PRG files are there): https://github.com/lgblgblgb/c64-sfx-cartridge-player/

lgblgblgb commented 3 years ago

I've just updated my last comment above since it seems I still haven't answered some question (if source is available), and other things.

gurcei commented 2 years ago

@gardners was interested in a direct link to the m65_play.prg file, to help with debugging opl3 behaviour on the hardware. So I'll add the direct link to it here:

Can also confirm, the song resides within the .prg file.

NOTE: .prg file needs to be loaded from C64-mode

lgblgblgb commented 2 years ago

@gurcei Yes, I can confirm it contains the "song" itself. In fact, this is my old SFX Sound Expander DRO player, the C64 and MEGA65 version is almost the same byte-by-byte, really the only difference that MEGA65 version uses the MEGA65 specific registers to play, but otherwise the same, ie even the MEGA65 version needs to be loaded in C64 mode.

lydon42 commented 1 year ago

@lgblgblgb @gardners what is the state of this?

lgblgblgb commented 1 year ago

@lydon42

@lgblgblgb @gardners what is the state of this?

As far as I know, it's in the VHDL but - IIRC - @gardners mentioned that for some unknown reason it does not produce any audio though it should. Xemu emulates this already and works. As I've mentioned, I also have my own test programs (works with Xemu) playing music this way so that can be used to test/debug MEGA65 implementation of the OPL3. But that's about all I know. Personally I would love if this works on real hardware too, some not finished (and secret, hehe) project of mine would use OPL3 for example (well, I know it's not an important factor here ...).

bjotos commented 6 months ago

Found today a bug in the opl2.v implementation: https://github.com/MEGA65/mega65-core/blob/f9385701f67c4cd28a92f6af27ad7abe601699e6/src/verilog/opl2.v#L173 This line resets all OPL registers to zero.

Since the underlying code makes use of the (OPL3-only) CHA/CHB bits https://github.com/MEGA65/mega65-core/blob/f9385701f67c4cd28a92f6af27ad7abe601699e6/src/verilog/opl2.v#L370 this causes channels to output zero.

According to various sources (YMF-704c manual, Nuked-OPL3), in compatibility mode the CHA and CHB bits of $C0-$C8 are not reset, and should default to '1'.

Thus, proper fix would be to change Line 370/371 to assign constant 1'b1 to cha[i] / chb[i].

see also https://discord.com/channels/719326990221574164/878463611952042044/1206645406428307456

Note: The OPL2 seems to work only via SFX module register range, i.e. via $7FFDF40, $7FFDF50.

S/W workaround is: POKE $7FFDF40,$C0: POKE $7FFDF50,$F0: REM ENABLE OUTPUT OF VOICE0 ON ALL CHANNELS (do this for $C0..$C8)

bjotos commented 6 months ago

Here is an assembler snippet (.s & .PRG) which programs Audio Mixer & OPL2 registers for Voice #0 and then triggers 6x Voice #0 OPL2Test.zip This program also incorporates aforementioned software W/A by programming $C0-$C8 to $F0.

This code works on real HW (Mega65 R3) and can be repeated multiple times (returns to BASIC). Should display WHITE border, with "glitching Black" at bottom when re-triggering sound. That is value read-back from $7FFDF60 written into $D020.

To read-back correct value, I have added the OPLWait() Macro, which just counts down X from $98 to zero. Lower values (i.e. $90) causes $7FFDF60 to not always reflect proper status.

lydon42 commented 2 weeks ago

So... this seems to be in release-0.96, and it seems people written programs for it. @bjotos @lgblgblgb is this finished and we can close it?

bjotos commented 2 weeks ago

Right now, we have a very limited (partially working, wrong reset defaults) OPL2 implementation, which was derived from a OPL3 implementation by stripping a lot of functionality.

Intend of that specific OPL2 implementation was to play DOOM "midi" files, which represent a very limited OPL2 feature-set.

My samples above are only testing OPL2 functions (play-back of DOSBox .DRO files for OPL2) and show lots of glitches (which could be my poor player and/or the implementation).

As such I'd not agree on this is finished at all ;)

gardners commented 2 weeks ago

ok, then let's leave it open, and it would seem that it will need considerable love from someone at some point. OR we make a M65 specific FM design, but I think there is value in having a proper OPL3.