FPGA Genesis with Sound

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

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

Post by Chilly Willy » Fri Dec 14, 2012 6:55 pm

I've always loved FPGAArcade! Nice work there. :D

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Wed Dec 04, 2013 8:29 pm

Hi,

Sorry for bumping an old thread, but I'm really interested in getting the sound support added to Gregory's fpgagen code.

@Shaho - have you made any more progress on this project, and do you still intend on releasing the source at some point?

If not, I'll have a go at adding the YM chip to the source.

I mainly use Verilog though, so VHDL is a bit slow going at times.
(I can convert to Verilog with X-HDL in most cases though.)

I'm having some major problems with my DE1 board and corrupted graphics with certain cores? It's not just fpgagen, it happens with Mike Stirling's BBC / Speccy cores too, so I'm fairly certain my board is faulty in some way.

I was talking to Gregory (Torlus) via Facebook earlier, and he sent me some newer source code for fpgagen. It's still not working properly on my board, so I'll have to RMA it. :(

I have ISSI SRAM / SDRAM chips on it, and I even replaced the 90ns Flash chip with a new 70ns one because some people have said this could cause issues with certain code.

I'm 99% sure now that the Cyclone II chip on my board is faulty, or the SRAM. :(

The strange thing is, many of the PACE project cores run fine on my DE1, and the graphics glitches with other cores do change depending on minor code changes before compilation?

The Minimig core runs perfectly fine on my board as well (once I found the correct version), which is really strange?

Anyway, I'd love to get fpgagen running properly, and with audio support.
I have a couple of those Atgames clones, which have pretty bad audio, and are not as easy to modify / add games too.

I have a few cheap FPGA boards from China, but their chips don't have quite enough logic for fpgagen (and definitely not enough to run the Minimig core).

I'm also hoping to add Sega CD support to the DE1 if I can get it running reliably first.

OzOnE.

Shaho
Interested
Posts: 10
Joined: Mon Nov 26, 2012 2:07 pm

Post by Shaho » Thu Dec 05, 2013 10:11 pm

Glad someone is still interested in this! I've been super lazy and haven't updated or cleaned up the code as intended, but the source is available at http://sourceforge.net/projects/teamgenesis/ if you want to dig through it. It's REALLY ugly in some places because I decided to use signed and unsigned types in VHDL, and didn't have a good grasp of it when I started.

The files you'll be most interested in for audio are fm.vhd, fm_chan.vhd, fm_chan3.vhd, and psg.vhd. fm.vhd is the block instantiation of the YM2612, and includes four fm_chans and two fm_chan3s (representing special channels 3 and 6). To be honest, most of the functionality between fm_chan and fm_chan3 is duplicated, and should be one file with a config flag for channel 3 mode. Also, psg.vhd is the programmable sound generator, which is pretty straightforward. Some of the code in gen_top.vhd re-routes the audio to the AC97 sound driver that we had on our board, but it could be changed to whatever sound output driver you have.

Hope this helps! Good luck on your project. Feel free to ask if you have any questions and I'll do my best to try to figure out what was going on. :D

kubilus1
Very interested
Posts: 237
Joined: Thu Aug 16, 2012 2:25 am
Contact:

Post by kubilus1 » Fri Dec 06, 2013 1:37 am

I've been quietly keeping an eye on this as well. Very interesting project. I've always wanted to learn more about FPGAs and VHDL and stuff.

A friend of mine is thinking about making a VHDL Sega System 16 board for arcade replacement, I think this would be a good start for that. The genesis and System 16 board use a lot of the same components.

Good work!

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Fri Dec 06, 2013 1:44 pm

That's fantastic, Shaho!

Thanks for the reply.

I've been looking at trying to implement the YM chip myself, but it would have taken me months.

I took a look at the Exodus emulator from Nemesis, it's also an amazing piece of work, but the number of registers in the YM chip looked very daunting. lol

I've just been trying to convert some of Gregory's original VHDL files to Verilog with the help of X-HDL. It's sort of running now, but it's screwed up the VDP somewhere.

I find VHDL quite frustrating, and progress is much slower than with Verilog, so I'll try to convert as much as I can to Verilog.
(it's a good learning experience anyway, as I want to learn about the VDP and audio chips.)

If I manage to get your sound support working on the DE1, I will post the project files on here and on a few other forums. I hope you don't mind me re-post your files, as long as it is all working OK?

I also use Altera / Quartus as I don't get on with Xilinx ISE very well.
Hopefully I can port everything back to the DE1 OK. ;)


Many thanks again,
OzOnE.

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Fri Dec 06, 2013 3:02 pm

Hi, again,

I've fallen at the first hurdle. lol

I've been tearing my hair out battling with VHDL. It's a bit evil... :twisted:

I added your FM files to the project, and I'm just trying to hook up the FM_OUT output port to some GPIO pins for testing...

fm : entity work.gen_fm
port map(
RST_N => T80_RESET_N, -- gen-hw.txt line 328
CLK => VCLK,

SEL => FM_SEL,
A => FM_A,
RNW => FM_RNW,
UDS_N => FM_UDS_N,
LDS_N => FM_LDS_N,
DI => FM_DI,
DO => FM_DO,
DTACK_N => FM_DTACK_N,

REG_OUT => open,
FM_OUT => GPIO_1(35 downto 20)
);


But FM_OUT is Signed of course, so Quartus complains with the error...

Error (10381): VHDL Type Mismatch error at gen_top.vhd(660): indexed name returns a value whose type does not match "SIGNED", the type of the target expression

I've tried changing the source file to unsigned, std_logic_vector etc.
I've also tried doing a CONV_STD_LOGIC_VECTOR, but I don't really know what I'm doing.

I can understand the basic concepts behind the signed types, and I'm guessing it's designed to preserve the signed bits while interpreting arithmetic functions etc., but I don't know how converting to a "bunch of bits" like std_logic_vector will affect things?

I'm not sure if the audio output module I want to use takes a signed type input either? I was going to use the one from the Pace or Minimig project.

I can't easily use your top level VHDL file, as all the signal names will be different to the DE1, so I thought it would be easier just to start instantiating the different blocks.

Please help! lol

I don't even know how to do simple assignments in VHDL.
In Verilog, it's easy, and I can get my brain around quite a few concepts in it.

Learning VHDL is like learning a foreign language (well, I suppose it is really).

At the moment, I'd love to just hear some of the music working.
I can easily use a simple sigma-delta modulator to output the audio to a signal pin for testing, then I can implement the proper I2S audio block for the DAC.


Thanks in advance,
OzOnE. :)

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Fri Dec 06, 2013 3:24 pm

Oh, never mind. I think I've got it now.

I just changed the output port in gen_fm.vhd to std_logic_vector instead of signed, then changed the line near the end...

FM_OUT <= std_logic_vector(OUTPUT);

I'm assuming the output will still be signed, but that's OK.

Just recompiling now. I hope it still fits into the DE1.

Fingers crossed. :?

OzOnE.

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Fri Dec 06, 2013 3:39 pm

Nope. Doesn't fit. :cry:

The original design (minus sound) took around 18,000 LE's (about the same as the Minimig tg68), but it's just compiled with the FM files included and now takes 51,690 LE's! :o

It's also using up 92% of the on-chip multipliers.

I will try disabling some of the channels and see if it will fit.
(DE1 Cyclone II only has 20,000 Logic Elements).

Don't get me wrong - I'm very grateful for these source files.
I will see if I can get it working.

I'll also try to stick with VHDL, I might like it a bit more if I can learn more about it. :wink:

OzOnE.

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Sat Dec 07, 2013 6:48 pm

Hi, all,

OK, got basic audio working on the DE1 now. :)

The chip only has enough room to fit the PSG and ONE channel of the YM though. It's literally 97% full right now.

I'm having strange issues with compilation still.
The audio output only works if I'm using channel 2 of the YM?

If I use say channel 1 or 3, the audio output doesn't work at all?
Even the PSG won't work in that case, and I can't figure out why?

I'm not using the proper DAC on the DE1, but instead I'm using a simple SigmaDelta DAC. This lets it output the audio on a single GPIO pin. ;)

This does save a lot of logic as well.

At the moment, I have the PSG and YM hooked up to separate output pins, so I can get a groovy "stereo" sound.

The DAC in the YM code is working fine, so I can finally hear the good old "SEGAAA!!!" sound and the drums.

The PSG sounds fine too, so I get all the sound effects like jumping in Sonic 2 etc.

But, the channel 2 I'm using from the YM code sounds quite weird, like it's an octave too low?

This is probably because it's supposed to be mixed with another FM operator or something? Not sure?

My DE1 is working a lot better after I replaced it's SRAM chip.
For some reason, it was giving corrupted data in a few places before?

@Shaho - thanks again for the code. :D

I'm starting to learn a bit more about VHDL now, so I suppose it's good that I stuck with it.

I did end up changing the gen_fm and psg outputs to std_logic_vector for the time being.

I also just flipped the MSB bit when assigning the audio output to the SigmaDelta blocks, to make it unsigned. I don't know if this is a "proper" way to do it, but it sounds quite good to me (apart from the obvious YM issues).

The audio is simply routed to two GPIO pins, so it will need an R/C filter on each pin. I'm just using 3K3 series resistors for now, as I haven't calculated a suitable capacitor value yet.

The SigDelta blocks are using MCLK as the master clock.
Not sure if this is is maybe too high, or what the optimum might be for the audio?

@Shaho - Do you think the YM channels could be trimmed down in some way to reduce the amount of logic needed?

Maybe the audio precision could be reduced a fair bit without loosing too much quality?

Quartus is saying that each YM channel needs over 500 Logic Elements to fit, which is quite a lot. It's also using all the on-chip multiplier blocks. lol

I will try adding a real YM chip to the DE1 as well.

After reading a lot of the work done by Nemesis and others, I'm interested in comparing the VHDL code to the real thing.

Also, I've updated Gregory's VDP code with most of the changes from your code. I don't know what the extra signals are for though?...

I can see you used internal RAM blocks rather than SRAM, so I've kept it as SRAM on the DE1.

But, I did add all the other differences, like the extra "RD3" Read signals etc...

type vmc_t is (
VMC_IDLE,
VMC_BGB_RD1,
VMC_BGB_RD2,
VMC_BGB_RD3,
VMC_BGA_RD1,
VMC_BGA_RD2,
VMC_BGA_RD3,
VMC_SP1_RD1,
VMC_SP1_RD2,
VMC_SP1_RD3,
VMC_SP2_RD1,
VMC_SP2_RD2,
VMC_SP2_RD3,
VMC_DT_ACC1,
VMC_DT_ACC2,
VMC_DT_ACC3
);
signal VMC : vmc_t;


And I added the other changes in the VDP logic, but kept the VRAM_DTACK_N stuff enabled...


when VMC_BGB_RD1 => -- BACKGROUND B
FF_VRAM_OE_N <= '0';
FF_VRAM_WE_N <= '1';
FF_VRAM_UB_N <= '0';
FF_VRAM_LB_N <= '0';
FF_VRAM_SEL <= '1';

--VMC <= VMC_BGB_RD2;
VMC <= VMC_BGB_RD3;

when VMC_BGB_RD2 =>
VMC <= VMC_BGB_RD3;

when VMC_BGB_RD3 =>
if VRAM_DTACK_N = '0' then
BGB_VRAM_DO <= VRAM_DO;
FF_VRAM_CE_N <= '1';
FF_VRAM_OE_N <= '1';
FF_VRAM_WE_N <= '1';
FF_VRAM_UB_N <= '1';
FF_VRAM_LB_N <= '1';

BGB_DTACK_N <= '0';

FF_VRAM_SEL <= '0';

VMC <= VMC_IDLE;
end if;



I was wondering if you remember what the extra RD3 signals are for, or why the logic is slightly different with the extra parts like this?...

when VMC_BGB_RD2 =>
VMC <= VMC_BGB_RD3;


I'm just confirming with Grégory if it's OK to post the updated DE1 code.
Should be fine, since they're both public anyway, but I want to stress that this is not an "official" release in any way, and just something for DE1 owners to have a play with.

It could also be used on other FPGA boards of course. They'd just need to port your code to it. 8)

Oh, I also added your gen_io module, so player two inputs are on GPIO pins. It needs some pull-ups though, as you can currently control Miles "Tails" Prower by merely touching the pins! lol


OzOnE.

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Sat Dec 07, 2013 7:11 pm

Does anyone know how the interlaced modes are supposed to work on things like the Sonic 2 two-player split screen?

It's scrolling the screens around OK, but all the graphics blocks are the wrong ones / corrupted?

I've noticed a few other strange things too...

I'm using Switches 3 and 2 to select between different 512KB blocks in Flash (for different game ROMs), and when I switch to Thunder Force IV, it has no audio at all?

I don't know if it's not using the same audio channels, or if something else weird is going on?

Also - when I hear the "SEGAAA!" logo, the pitch is slightly different each time? This seems to be after the level demos in Sonic 2.

eg. After the Casino Night Zone, the SEGA! voice is slightly higher pitched?

I wonder how accurate the Z80 and 68K cores are now?

This has been quite fun btw. :)

Loved the Genesis when it was released (or Mega Drive, as it's known over here in the UK).

My sister got the Mega Drive in 1992 (she is a few years older than me), and she played Sonic 2 for months. She also had the Menacer pack, with Ready Aim Tomatoes. Great fun!

It's still an impressive console, and more fun than the expensive Neo Geo in a lot of ways (although I did buy an MVS and NGCD recently).

OzOnE.

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Sat Dec 07, 2013 11:46 pm

OK,

Got the REAL YM2612 chip hooked up now, and it's working great! :D

Image

Image

Soldering isn't amazing, but I'm impatient...

Image

Sonic 2 running (slight glitch below Miles, but everything else apart from split-screen mode is great...

Image

I was very surprised that it actually worked after a bit of minor fiddling with the code. It wasn't exactly clear which half of the 16-bit data bus should go to the chip.

I also thought I fried the chip at first, as it was getting super hot.
This was caused by bus contention, because I hadn't initialized the IO pins correctly (chip was trying to /Read and /Write at the same time!).

The sound is very quiet, as it needs an opamp buffer.
The PSG is still working via a separate pin on the FPGA.

This might be the solution for decent sound on the DE1 - The YM chips can be bought cheaply from China, and it's easy enough to connect.

I just need to add a few joystick ports now, then see if I can get SD card support working.

I might have to abandon the idea of squeezing in all the YM channels on the FPGA itself, there just isn't quite enough room on the DE1.

I'd prefer a "neat" solution though if possible. I like the idea of having everything on one chip.

A lot of the FPGA cores are good enough now that I'm thinking of selling my real machines like the Amiga 600, BBC Micro, ZX Spectrum etc.

Still having very strange issues with Quartus.
The other day when I first tried to compile Grégory's code, it was doing things like this...

Image

I found that it's best to delete all the Quartus / Altera files in the Documents folder, and delete the db folder in the project, then turn off all the optimization junk and recompile.

If the YM chip can't be made to fit the DE1, it might be worth getting some simple PCBs made up for people who want to run things like the Minimig and Genesis cores on it.

OzOnE.

OzOnE
Interested
Posts: 23
Joined: Wed Dec 04, 2013 3:49 pm

Post by OzOnE » Sun Dec 08, 2013 12:01 am

Here's an example of two player split-screen mode...

Image

Sorry it's a bit blurry due to the movement.

Also, the stupid camera battery ran out just afterwards (as you can see by the date on the photo, it's an OLD camera. lol)

Does anyone know how the interlaced modes work on the Genesis?
Does it affect how the VDP accesses the graphics blocks?

If we can fix this, then it would be pretty much complete.

EDIT: Oh also - the music on Mickey Mouse: Castle Of Illusion is actually working, but it's running at about 1/16th of the proper speed?

I don't think this is the YM chip itself unless the music is running off the timers?

Actually, it's slightly more complex than that - I'm still running one channel of the YM inside the FPGA, and the core is getting it's status from that.

The real YM chip is only being written TO, there are no reads coming back from it yet.

I wonder what would make the music run super slow?
Surely it's more likely to do with the Z80 timing rather than the YM chip?


OzOnE.

Jorge Nuno
Very interested
Posts: 374
Joined: Mon Jun 11, 2007 3:09 am
Location: Azeitão, PT

Post by Jorge Nuno » Sun Dec 08, 2013 1:28 am

On interlace mode 2 tiles become 8x16 pixels, the nametable tile pointer is now halved, and of course only odd or even lines are rendered (though you may output them all as if it were a 320x640 resolution).
I think horizontal line scrolling affects now pairs of lines 0/1, 2/3, 4/5, etc

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sun Dec 08, 2013 10:25 am

Quackshot and Castle of Illusion (among others) use YM2612 timers but I think I remember the sound driver is using them a bit differently from other games and those two games had problem when timer A or B was not properly emulated and timer overflow bits not properly returned in FM status.

when enabled, Timer A is decremented every FM clock (VCLK / 144) and Timer B is decremented evey 16th FM clock so maybe Timer A is your problem here, make sure you didn't inverted the bits for Timer A and B in FM register $27.

Also, timers are only reloaded when they overflow or when the LOAD bit changes from 0 to 1, not when Timer DATA registers or ENABLE bit are modified...

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sun Dec 08, 2013 11:06 am

Jorge Nuno wrote:On interlace mode 2 tiles become 8x16 pixels, the nametable tile pointer is now halved, and of course only odd or even lines are rendered (though you may output them all as if it were a 320x640 resolution).
I think horizontal line scrolling affects now pairs of lines 0/1, 2/3, 4/5, etc
vertical scrolling is also affected by interlace mode 2, an extra bit is used in VSRAM so VSCROLL value is now 11-bit instead of 10-bit (bit 0 ignored)

Post Reply