Update to v100r02 release.
byuu says:
Sigh ... I'm really not a good person. I'm inherently selfish.
My responsibility and obligation right now is to work on loki, and
then on the Tengai Makyou Zero translation, and then on improving the
Famicom emulation.
And yet ... it's not what I really want to do. That shouldn't matter;
I should work on my responsibilities first.
Instead, I'm going to be a greedy, self-centered asshole, and work on
what I really want to instead.
I'm really sorry, guys. I'm sure this will make a few people happy,
and probably upset even more people.
I'm also making zero guarantees that this ever gets finished. As always,
I wish I could keep these things secret, so if I fail / give up, I could
just drop it with no shame. But I would have to cut everyone out of the
WIP process completely to make it happen. So, here goes ...
This WIP adds the initial skeleton for Sega Mega Drive / Genesis
emulation. God help us.
(minor note: apparently the new extension for Mega Drive games is .md,
neat. That's what I chose for the folders too. I thought it was .smd,
so that'll be fixed in icarus for the next WIP.)
(aside: this is why I wanted to get v100 out. I didn't want this code in
a skeleton state in v100's source. Nor did I want really broken emulation,
which the first release is sure to be, tarring said release.)
...
So, basically, I've been ruminating on the legacy I want to leave behind
with higan. 3D systems are just plain out. I'm never going to support
them. They're too complex for my abilities, and they would run too slowly
with my design style. I'm not willing to compromise my design ideals. And
I would never want to play a 3D game system at native 240p/480i resolution
... but 1080p+ upscaling is not accurate, so that's a conflict I want
to avoid entirely. It's also never going to emulate computer systems
(X68K, PC-98, FM-Towns, etc) because holy shit that would completely
destroy me. It's also never going emulate arcade machines.
So I think of higan as a collection of 2D emulators for consoles
and handhelds. I've gone over every major 2D gaming system there is,
looking for ones with games I actually care about and enjoy. And I
basically have five of those systems supported already. Looking at the
remaining list, I see only three systems left that I have any interest
in whatsoever: PC-Engine, Master System, Mega Drive. Again, I'm not in
any way committing to emulating any of these, but ... if I had all of
those in higan, I think I'd be content to really, truly, finally stop
writing more emulators for the rest of my life.
And so I decided to tackle the most difficult system first. If I'm
successful, the Z80 core should cover a lot of the work on the SMS. And
the HuC6280 should land somewhere between the NES and SNES in terms of
difficulty ... closer to the NES.
The systems that just don't appeal to me at all, which I will never touch,
include, but are not limited to:
* Atari 2600/5200/7800
* Lynx
* Jaguar
* Vectrex
* Colecovision
* Commodore 64
* Neo-Geo
* Neo-Geo Pocket / Color
* Virtual Boy
* Super A'can
* 32X
* CD-i
* etc, etc, etc.
And really, even if something were mildly interesting in there ... we
have to stop. I can't scale infinitely. I'm already way past my limit,
but I'm doing this anyway. Too many cores bloats everything and kills
quality on everything. I don't want higan to become MESS v2.
I don't know what I'll do about the Famicom Disk System, PC-Engine CD,
and Mega CD. I don't think I'll be able to achieve 60fps emulating the
Mega CD, even if I tried to.
I don't know what's going to happen here with even the Mega Drive. Maybe
I'll get driven crazy with the documentation and quit. Maybe it'll end
up being too complicated and I'll quit. Maybe the emulation will end up
way too slow and I'll give up. Maybe it'll take me seven years to get
any games playable at all. Maybe Steve Snake, AamirM and Mike Pavone
will pool money to hire a hitman to come after me. Who knows.
But this is what I want to do, so ... here goes nothing.
2016-07-09 04:21:37 +00:00
|
|
|
//Yamaha YM2612
|
|
|
|
|
|
|
|
struct YM2612 : Thread {
|
Update to v102r08 release.
byuu says:
Changelog:
- PCE: restructured VCE, VDCs to run one scanline at a time
- PCE: bound VDCs to 1365x262 timing (in order to decouple the VDCs
from the VCE)
- PCE: the two changes above allow save states to function; also
grants a minor speed boost
- PCE: added cheat code support (uses 21-bit bus addressing; compare
byte will be useful here)
- 68K: fixed `mov *,ccr` to read two bytes instead of one [Cydrak]
- Z80: emulated /BUSREQ, /BUSACK; allows 68K to suspend the Z80
[Cydrak]
- MD: emulated the Z80 executing instructions [Cydrak]
- MD: emulated Z80 interrupts (triggered during each Vblank period)
[Cydrak]
- MD: emulated Z80 memory map [Cydrak]
- MD: added stubs for PSG, YM2612 accesses [Cydrak]
- MD: improved bus emulation [Cydrak]
The PCE core is pretty much ready to go. The only major feature missing
is FM modulation.
The Mega Drive improvements let us start to see the splash screens for
Langrisser II, Shining Force, Shining in the Darkness. I was hoping I
could get them in-game, but no such luck. My Z80 implementation is
probably flawed in some way ... now that I think about it, I believe I
missed the BusAPU::reset() check for having been granted access to the
Z80 first. But I doubt that's the problem.
Next step is to implement Cydrak's PSG core into the Master System
emulator. Once that's in, I'm going to add save states and cheat code
support to the Master System core.
Next, I'll add the PSG core into the Mega Drive. Then I'll add the
'easy' PCM part of the YM2612. Then the rest of the beastly YM2612 core.
Then finally, cap things off with save state and cheat code support.
Should be nearing a new release at that point.
2017-02-20 08:13:10 +00:00
|
|
|
shared_pointer<Emulator::Stream> stream;
|
|
|
|
|
2016-07-10 05:28:26 +00:00
|
|
|
static auto Enter() -> void;
|
|
|
|
auto main() -> void;
|
2017-03-01 20:40:55 +00:00
|
|
|
auto sample() -> void;
|
2016-07-10 05:28:26 +00:00
|
|
|
auto step(uint clocks) -> void;
|
|
|
|
|
|
|
|
auto power() -> void;
|
Update to v102r08 release.
byuu says:
Changelog:
- PCE: restructured VCE, VDCs to run one scanline at a time
- PCE: bound VDCs to 1365x262 timing (in order to decouple the VDCs
from the VCE)
- PCE: the two changes above allow save states to function; also
grants a minor speed boost
- PCE: added cheat code support (uses 21-bit bus addressing; compare
byte will be useful here)
- 68K: fixed `mov *,ccr` to read two bytes instead of one [Cydrak]
- Z80: emulated /BUSREQ, /BUSACK; allows 68K to suspend the Z80
[Cydrak]
- MD: emulated the Z80 executing instructions [Cydrak]
- MD: emulated Z80 interrupts (triggered during each Vblank period)
[Cydrak]
- MD: emulated Z80 memory map [Cydrak]
- MD: added stubs for PSG, YM2612 accesses [Cydrak]
- MD: improved bus emulation [Cydrak]
The PCE core is pretty much ready to go. The only major feature missing
is FM modulation.
The Mega Drive improvements let us start to see the splash screens for
Langrisser II, Shining Force, Shining in the Darkness. I was hoping I
could get them in-game, but no such luck. My Z80 implementation is
probably flawed in some way ... now that I think about it, I believe I
missed the BusAPU::reset() check for having been granted access to the
Z80 first. But I doubt that's the problem.
Next step is to implement Cydrak's PSG core into the Master System
emulator. Once that's in, I'm going to add save states and cheat code
support to the Master System core.
Next, I'll add the PSG core into the Mega Drive. Then I'll add the
'easy' PCM part of the YM2612. Then the rest of the beastly YM2612 core.
Then finally, cap things off with save state and cheat code support.
Should be nearing a new release at that point.
2017-02-20 08:13:10 +00:00
|
|
|
|
|
|
|
//io.cpp
|
|
|
|
auto readStatus() -> uint8;
|
|
|
|
auto writeAddress(uint9 data) -> void;
|
|
|
|
auto writeData(uint8 data) -> void;
|
Update to v102r12 release.
byuu says:
Changelog:
- MD/PSG: fixed 68K bus Z80 status read address location
- MS, GG, MD/PSG: channels post-decrement their counters, not
pre-decrement [Cydrak]¹
- MD/VDP: cache screen width registers once per scanline; screen
height registers once per frame
- MD/VDP: support 256-width display mode (used in Shining Force, etc)
- MD/YM2612: implemented timers²
- MD/YM2612: implemented 8-bit PCM DAC²
- 68000: TRAP instruction should index the vector location by 32 (eg
by 128 bytes), fixes Shining Force
- nall: updated hex(), octal(), binary() functions to take uintmax
instead of template<typename T> parameter³
¹: this one makes an incredible difference. Sie noticed that lots of
games set a period of 0, which would end up being a really long period
with pre-decrement. By fixing this, noise shows up in many more games,
and sounds way better in games even where it did before. You can hear
extra sound on Lunar - Sanposuru Gakuen's title screen, the noise in
Sonic The Hedgehog (Mega Drive) sounds better, etc.
²: this also really helps sound. The timers allow PSG music to play
back at the correct speed instead of playing back way too quickly. And
the PCM DAC lets you hear a lot of drum effects, as well as the
"Sega!!" sound at the start of Sonic the Hedgehog, and the infamous,
"Rise from your grave!" line from Altered Beast.
Still, most music on the Mega Drive comes from the FM channels, so
there's still not a whole lot to listen to.
I didn't implement Cydrak's $02c test register just yet. Sie wasn't 100%
certain on how the extended DAC bit worked, so I'd like to play it a
little conservative and get sound working, then I'll go back and add a
toggle or something to enable undocumented registers, that way we can
use that to detect any potential problems they might be causing.
³: unfortunately we lose support for using hex() on nall/arithmetic
types. If I have a const Pair& version of the function, then the
compiler gets confused on whether Natural<32> should use uintmax or
const Pair&, because compilers are stupid, and you can't have explicit
arguments in overloaded functions. So even though either function would
work, it just decides to error out instead >_>
This is actually really annoying, because I want hex() to be useful for
printing out nall/crypto keys and hashes directly.
But ... this change had to be made. Negative signed integers would crash
programs, and that was taking out my 68000 disassembler.
2017-02-27 08:45:51 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
struct IO {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint9 address = 0;
|
Update to v102r12 release.
byuu says:
Changelog:
- MD/PSG: fixed 68K bus Z80 status read address location
- MS, GG, MD/PSG: channels post-decrement their counters, not
pre-decrement [Cydrak]¹
- MD/VDP: cache screen width registers once per scanline; screen
height registers once per frame
- MD/VDP: support 256-width display mode (used in Shining Force, etc)
- MD/YM2612: implemented timers²
- MD/YM2612: implemented 8-bit PCM DAC²
- 68000: TRAP instruction should index the vector location by 32 (eg
by 128 bytes), fixes Shining Force
- nall: updated hex(), octal(), binary() functions to take uintmax
instead of template<typename T> parameter³
¹: this one makes an incredible difference. Sie noticed that lots of
games set a period of 0, which would end up being a really long period
with pre-decrement. By fixing this, noise shows up in many more games,
and sounds way better in games even where it did before. You can hear
extra sound on Lunar - Sanposuru Gakuen's title screen, the noise in
Sonic The Hedgehog (Mega Drive) sounds better, etc.
²: this also really helps sound. The timers allow PSG music to play
back at the correct speed instead of playing back way too quickly. And
the PCM DAC lets you hear a lot of drum effects, as well as the
"Sega!!" sound at the start of Sonic the Hedgehog, and the infamous,
"Rise from your grave!" line from Altered Beast.
Still, most music on the Mega Drive comes from the FM channels, so
there's still not a whole lot to listen to.
I didn't implement Cydrak's $02c test register just yet. Sie wasn't 100%
certain on how the extended DAC bit worked, so I'd like to play it a
little conservative and get sound working, then I'll go back and add a
toggle or something to enable undocumented registers, that way we can
use that to detect any potential problems they might be causing.
³: unfortunately we lose support for using hex() on nall/arithmetic
types. If I have a const Pair& version of the function, then the
compiler gets confused on whether Natural<32> should use uintmax or
const Pair&, because compilers are stupid, and you can't have explicit
arguments in overloaded functions. So even though either function would
work, it just decides to error out instead >_>
This is actually really annoying, because I want hex() to be useful for
printing out nall/crypto keys and hashes directly.
But ... this change had to be made. Negative signed integers would crash
programs, and that was taking out my 68000 disassembler.
2017-02-27 08:45:51 +00:00
|
|
|
} io;
|
|
|
|
|
2017-03-01 20:40:55 +00:00
|
|
|
struct LFO {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 enable = 0;
|
|
|
|
uint3 rate = 0;
|
|
|
|
uint32 clock = 0;
|
|
|
|
uint32 divider = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} lfo;
|
|
|
|
|
|
|
|
struct DAC {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 enable = 0;
|
|
|
|
uint8 sample = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} dac;
|
|
|
|
|
|
|
|
struct Envelope {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint32 clock = 0;
|
|
|
|
uint32 divider = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} envelope;
|
|
|
|
|
Update to v102r12 release.
byuu says:
Changelog:
- MD/PSG: fixed 68K bus Z80 status read address location
- MS, GG, MD/PSG: channels post-decrement their counters, not
pre-decrement [Cydrak]¹
- MD/VDP: cache screen width registers once per scanline; screen
height registers once per frame
- MD/VDP: support 256-width display mode (used in Shining Force, etc)
- MD/YM2612: implemented timers²
- MD/YM2612: implemented 8-bit PCM DAC²
- 68000: TRAP instruction should index the vector location by 32 (eg
by 128 bytes), fixes Shining Force
- nall: updated hex(), octal(), binary() functions to take uintmax
instead of template<typename T> parameter³
¹: this one makes an incredible difference. Sie noticed that lots of
games set a period of 0, which would end up being a really long period
with pre-decrement. By fixing this, noise shows up in many more games,
and sounds way better in games even where it did before. You can hear
extra sound on Lunar - Sanposuru Gakuen's title screen, the noise in
Sonic The Hedgehog (Mega Drive) sounds better, etc.
²: this also really helps sound. The timers allow PSG music to play
back at the correct speed instead of playing back way too quickly. And
the PCM DAC lets you hear a lot of drum effects, as well as the
"Sega!!" sound at the start of Sonic the Hedgehog, and the infamous,
"Rise from your grave!" line from Altered Beast.
Still, most music on the Mega Drive comes from the FM channels, so
there's still not a whole lot to listen to.
I didn't implement Cydrak's $02c test register just yet. Sie wasn't 100%
certain on how the extended DAC bit worked, so I'd like to play it a
little conservative and get sound working, then I'll go back and add a
toggle or something to enable undocumented registers, that way we can
use that to detect any potential problems they might be causing.
³: unfortunately we lose support for using hex() on nall/arithmetic
types. If I have a const Pair& version of the function, then the
compiler gets confused on whether Natural<32> should use uintmax or
const Pair&, because compilers are stupid, and you can't have explicit
arguments in overloaded functions. So even though either function would
work, it just decides to error out instead >_>
This is actually really annoying, because I want hex() to be useful for
printing out nall/crypto keys and hashes directly.
But ... this change had to be made. Negative signed integers would crash
programs, and that was taking out my 68000 disassembler.
2017-02-27 08:45:51 +00:00
|
|
|
struct TimerA {
|
|
|
|
//timer.cpp
|
|
|
|
auto run() -> void;
|
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 enable = 0;
|
|
|
|
uint1 irq = 0;
|
|
|
|
uint1 line = 0;
|
|
|
|
uint10 period = 0;
|
|
|
|
uint10 counter = 0;
|
Update to v102r12 release.
byuu says:
Changelog:
- MD/PSG: fixed 68K bus Z80 status read address location
- MS, GG, MD/PSG: channels post-decrement their counters, not
pre-decrement [Cydrak]¹
- MD/VDP: cache screen width registers once per scanline; screen
height registers once per frame
- MD/VDP: support 256-width display mode (used in Shining Force, etc)
- MD/YM2612: implemented timers²
- MD/YM2612: implemented 8-bit PCM DAC²
- 68000: TRAP instruction should index the vector location by 32 (eg
by 128 bytes), fixes Shining Force
- nall: updated hex(), octal(), binary() functions to take uintmax
instead of template<typename T> parameter³
¹: this one makes an incredible difference. Sie noticed that lots of
games set a period of 0, which would end up being a really long period
with pre-decrement. By fixing this, noise shows up in many more games,
and sounds way better in games even where it did before. You can hear
extra sound on Lunar - Sanposuru Gakuen's title screen, the noise in
Sonic The Hedgehog (Mega Drive) sounds better, etc.
²: this also really helps sound. The timers allow PSG music to play
back at the correct speed instead of playing back way too quickly. And
the PCM DAC lets you hear a lot of drum effects, as well as the
"Sega!!" sound at the start of Sonic the Hedgehog, and the infamous,
"Rise from your grave!" line from Altered Beast.
Still, most music on the Mega Drive comes from the FM channels, so
there's still not a whole lot to listen to.
I didn't implement Cydrak's $02c test register just yet. Sie wasn't 100%
certain on how the extended DAC bit worked, so I'd like to play it a
little conservative and get sound working, then I'll go back and add a
toggle or something to enable undocumented registers, that way we can
use that to detect any potential problems they might be causing.
³: unfortunately we lose support for using hex() on nall/arithmetic
types. If I have a const Pair& version of the function, then the
compiler gets confused on whether Natural<32> should use uintmax or
const Pair&, because compilers are stupid, and you can't have explicit
arguments in overloaded functions. So even though either function would
work, it just decides to error out instead >_>
This is actually really annoying, because I want hex() to be useful for
printing out nall/crypto keys and hashes directly.
But ... this change had to be made. Negative signed integers would crash
programs, and that was taking out my 68000 disassembler.
2017-02-27 08:45:51 +00:00
|
|
|
} timerA;
|
|
|
|
|
|
|
|
struct TimerB {
|
|
|
|
//timer.cpp
|
|
|
|
auto run() -> void;
|
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 enable = 0;
|
|
|
|
uint1 irq = 0;
|
|
|
|
uint1 line = 0;
|
|
|
|
uint8 period = 0;
|
|
|
|
uint8 counter = 0;
|
|
|
|
uint4 divider = 0;
|
Update to v102r12 release.
byuu says:
Changelog:
- MD/PSG: fixed 68K bus Z80 status read address location
- MS, GG, MD/PSG: channels post-decrement their counters, not
pre-decrement [Cydrak]¹
- MD/VDP: cache screen width registers once per scanline; screen
height registers once per frame
- MD/VDP: support 256-width display mode (used in Shining Force, etc)
- MD/YM2612: implemented timers²
- MD/YM2612: implemented 8-bit PCM DAC²
- 68000: TRAP instruction should index the vector location by 32 (eg
by 128 bytes), fixes Shining Force
- nall: updated hex(), octal(), binary() functions to take uintmax
instead of template<typename T> parameter³
¹: this one makes an incredible difference. Sie noticed that lots of
games set a period of 0, which would end up being a really long period
with pre-decrement. By fixing this, noise shows up in many more games,
and sounds way better in games even where it did before. You can hear
extra sound on Lunar - Sanposuru Gakuen's title screen, the noise in
Sonic The Hedgehog (Mega Drive) sounds better, etc.
²: this also really helps sound. The timers allow PSG music to play
back at the correct speed instead of playing back way too quickly. And
the PCM DAC lets you hear a lot of drum effects, as well as the
"Sega!!" sound at the start of Sonic the Hedgehog, and the infamous,
"Rise from your grave!" line from Altered Beast.
Still, most music on the Mega Drive comes from the FM channels, so
there's still not a whole lot to listen to.
I didn't implement Cydrak's $02c test register just yet. Sie wasn't 100%
certain on how the extended DAC bit worked, so I'd like to play it a
little conservative and get sound working, then I'll go back and add a
toggle or something to enable undocumented registers, that way we can
use that to detect any potential problems they might be causing.
³: unfortunately we lose support for using hex() on nall/arithmetic
types. If I have a const Pair& version of the function, then the
compiler gets confused on whether Natural<32> should use uintmax or
const Pair&, because compilers are stupid, and you can't have explicit
arguments in overloaded functions. So even though either function would
work, it just decides to error out instead >_>
This is actually really annoying, because I want hex() to be useful for
printing out nall/crypto keys and hashes directly.
But ... this change had to be made. Negative signed integers would crash
programs, and that was taking out my 68000 disassembler.
2017-02-27 08:45:51 +00:00
|
|
|
} timerB;
|
|
|
|
|
2017-03-01 20:40:55 +00:00
|
|
|
enum : uint { Attack, Decay, Sustain, Release };
|
|
|
|
|
|
|
|
struct Channel {
|
|
|
|
//channel.cpp
|
|
|
|
auto power() -> void;
|
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 leftEnable = 1;
|
|
|
|
uint1 rightEnable = 1;
|
2017-03-01 20:40:55 +00:00
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint3 algorithm = 0;
|
|
|
|
uint3 feedback = 0;
|
|
|
|
uint3 vibrato = 0;
|
|
|
|
uint2 tremolo = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint2 mode = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
|
|
|
|
struct Operator {
|
Update to v102r14 release.
byuu says:
Changelog:
- (MS,GG,MD)/PSG: flip output bit from noise channel [TmEE]
- MD/YM2612: rewrite YM2612::Channel functions to
YM2612::Channel::Operator functions¹
- MD/YM2612: pitch/octave I/O registers should set reload, not value
(fixes sound in most games)
- MD/YM2612: don't try to sign-extend raw PCM values (fixes Shining
Force opening music)
- MD/YM2612: various algorithm simplifications; conversions from
`*`, `/`, `%` to `<<`, `>>`; etc.
Overall ... Sonic the Hedgehog sounds really, really great. Almost
perfect, but there's a bit of clamping going on in the special zones.
Langrisser II sounds really great. Shining Force sounds pretty much
perfect. Bare Knucles (Streets of Rage) does pretty badly ... punches
sound more like dinging a salad fork on a wine glass, heh. Altered Beast
is extremely broken ... no music at the title screen, very distorted
in-game music. I suspect a bug outside of the YM2612 is affecting this
game.
So, the YM2612 emulation isn't perfect, but it's a really good start to
the most complex sound chip in all of higan. Hopefully the VRC7 and
YM2413 will prove to be less ferocious ... not that I'm in any rush to
work on either. The former is going to need the NES mapper rewrite to be
done first, and the latter is cool but not very necessary since all
those games have fallbacks to the inferior PSG audio.
But really ... I can't thank Cydrak enough for doing this for me. It
would have probably taken me months to parse through all of the
documentation on this chip (most of which is in a 55-page thread on
spritesmind that is filled with wrong/outdated information at the start,
and corrections as you go deeper.) Not to mention, learning about what
the hell detuning, low-frequency oscillation, tremolo, vibrato, etc were
all about. Or how those algorithms to compute the final output work. Or
the dozens of special cases littered in there to make everything sound
good. Fierce, nasty chip that.
Now the last real problem is save states ... the Mega Drive is going to
be the trickiest of all to implement with libco. There are lots of areas
where one chip will deadlock another chip while it completes some
operation. We don't have a choice but to force those stalls to abort
anyway, in order to let libco reach the start of its entry point once
again. I don't know what kind of impact that'll have on states ... I
suspect they'll work almost as reliably as the SNES does, but I can't
know that until I implement it. It's going to be pretty nasty, though.
¹: this basically removes a lot of unnecessary op. prefixes and the
need to capture `auto& op = operators[index]` at the start of every
function.
I wanted to have subfunctions like
`YM2612::Channel::Operator::Envelope::run()`, etc but unfortunately,
pretty much all of the envelope, phase, pitch, level functions need to
access each other's state.
2017-03-03 10:45:07 +00:00
|
|
|
Channel& channel;
|
|
|
|
Operator(Channel& channel) : channel(channel) {}
|
|
|
|
|
|
|
|
//channel.cpp
|
|
|
|
auto trigger(bool) -> void;
|
|
|
|
|
|
|
|
auto runEnvelope() -> void;
|
|
|
|
auto runPhase() -> void;
|
|
|
|
|
|
|
|
auto updateEnvelope() -> void;
|
|
|
|
auto updatePitch() -> void;
|
|
|
|
auto updatePhase() -> void;
|
|
|
|
auto updateLevel() -> void;
|
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 keyOn = 0;
|
|
|
|
uint1 lfoEnable = 0;
|
|
|
|
uint3 detune = 0;
|
|
|
|
uint4 multiple = 0;
|
|
|
|
uint7 totalLevel = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint16 outputLevel = 0x1fff;
|
|
|
|
int16 output = 0;
|
|
|
|
int16 prior = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
|
|
|
|
struct Pitch {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint11 value = 0;
|
|
|
|
uint11 reload = 0;
|
|
|
|
uint11 latch = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} pitch;
|
|
|
|
|
|
|
|
struct Octave {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint3 value = 0;
|
|
|
|
uint3 reload = 0;
|
|
|
|
uint3 latch = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} octave;
|
|
|
|
|
|
|
|
struct Phase {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint20 value = 0;
|
|
|
|
uint20 delta = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} phase;
|
|
|
|
|
|
|
|
struct Envelope {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint state = Release;
|
|
|
|
int rate = 0;
|
|
|
|
int divider = 11;
|
|
|
|
uint32 steps = 0;
|
|
|
|
uint10 value = 0x3ff;
|
|
|
|
|
|
|
|
uint2 keyScale = 0;
|
|
|
|
uint5 attackRate = 0;
|
|
|
|
uint5 decayRate = 0;
|
|
|
|
uint5 sustainRate = 0;
|
|
|
|
uint4 sustainLevel = 0;
|
|
|
|
uint5 releaseRate = 1;
|
2017-03-01 20:40:55 +00:00
|
|
|
} envelope;
|
|
|
|
|
|
|
|
struct SSG {
|
Update to v102r15 release.
byuu says:
Changelog:
- nall: added DSP::IIR::OnePole (which is a first-order IIR filter)
- FC/APU: removed strong highpass, weak hipass filters (and the
dummied out lowpass filter)
- MS,GG,MD/PSG: removed lowpass filter
- MS,GG,MD/PSG: audio was not being centered properly; removed
centering for now
- MD/YM2612: fixed clipping of accumulator from 18 signed bits to 14
signed bits (-0x2000 to +0x1fff) [Cydrak]
- MD/YM2612: removed lowpass filter
- PCE/PSG: audio was not being centered properly; removed centering
for now
First thing is that I've removed all of the ad-hoc audio filtering.
Emulator::Stream intrinsically provides a three-pass, second-order
biquad IIR butterworth lowpass filter that clips frequencies above 20KHz
with very good attenuation (as good as IIR gets, anyway.)
It doesn't really make sense to have the various cores running
additional lowpass filters. If we want to filter frequencies below
20KHz, then I can adapt Emulator::Audio::createStream() to take a cutoff
frequency value, and we can do it all at once, with much better quality.
Right now, I don't know what frequencies are best to cut off the various
other audio cores, so they're just gone for now.
As for the highpass filters for the Famicom core, well ... you don't get
aliasing from resampling low frequencies. And generally speaking, too
low a frequency will be inaudible anyway. All these were doing was
killing possible bass (if they were too strong.) We can add them again,
but only if someone can convert Ryphecha's ad-hoc magic integers into a
frequency cutoff. In which case, I'll use my biquad IIR filter to do it
even better. On this note, it may prove useful to do this for the MD PSG
as well, to try and head off unnecessary clamping when mixing with the
YM2612.
Finally, there was the audio centering issue that affected the
MS,GG,MD,PCE,SG cores. It was flooring the "silent" audio level, which
was resulting in extremely heavy distortion if you tried listening to
higan and, say, audacious at the same time. Without the botched
centering, this distortion is completely gone now.
However, without any centering, we've halved the potential volume range.
This means the audio slider in higan's audio settings panel will start
clamping twice as quickly. So ultimately, we need to figure out how to
fix the centering. This isn't as simple as just subtracting less. We
will probably have to center every individual audio channel before
summing them to do this properly.
Results:
On the Mega Drive, Altered Beast sounds quite a bit better, a lot less
distortion now. But it's still not perfect, especially sound effects.
Further, Bare Knuckle / Streets of Rage still has really bad sound
effects. It looks like I broke something in Cydrak's code when trying to
adapt it to my style =(
2017-03-06 20:23:22 +00:00
|
|
|
uint1 enable = 0;
|
|
|
|
uint1 attack = 0;
|
|
|
|
uint1 alternate = 0;
|
|
|
|
uint1 hold = 0;
|
|
|
|
uint1 invert = 0;
|
2017-03-01 20:40:55 +00:00
|
|
|
} ssg;
|
Update to v102r14 release.
byuu says:
Changelog:
- (MS,GG,MD)/PSG: flip output bit from noise channel [TmEE]
- MD/YM2612: rewrite YM2612::Channel functions to
YM2612::Channel::Operator functions¹
- MD/YM2612: pitch/octave I/O registers should set reload, not value
(fixes sound in most games)
- MD/YM2612: don't try to sign-extend raw PCM values (fixes Shining
Force opening music)
- MD/YM2612: various algorithm simplifications; conversions from
`*`, `/`, `%` to `<<`, `>>`; etc.
Overall ... Sonic the Hedgehog sounds really, really great. Almost
perfect, but there's a bit of clamping going on in the special zones.
Langrisser II sounds really great. Shining Force sounds pretty much
perfect. Bare Knucles (Streets of Rage) does pretty badly ... punches
sound more like dinging a salad fork on a wine glass, heh. Altered Beast
is extremely broken ... no music at the title screen, very distorted
in-game music. I suspect a bug outside of the YM2612 is affecting this
game.
So, the YM2612 emulation isn't perfect, but it's a really good start to
the most complex sound chip in all of higan. Hopefully the VRC7 and
YM2413 will prove to be less ferocious ... not that I'm in any rush to
work on either. The former is going to need the NES mapper rewrite to be
done first, and the latter is cool but not very necessary since all
those games have fallbacks to the inferior PSG audio.
But really ... I can't thank Cydrak enough for doing this for me. It
would have probably taken me months to parse through all of the
documentation on this chip (most of which is in a 55-page thread on
spritesmind that is filled with wrong/outdated information at the start,
and corrections as you go deeper.) Not to mention, learning about what
the hell detuning, low-frequency oscillation, tremolo, vibrato, etc were
all about. Or how those algorithms to compute the final output work. Or
the dozens of special cases littered in there to make everything sound
good. Fierce, nasty chip that.
Now the last real problem is save states ... the Mega Drive is going to
be the trickiest of all to implement with libco. There are lots of areas
where one chip will deadlock another chip while it completes some
operation. We don't have a choice but to force those stalls to abort
anyway, in order to let libco reach the start of its entry point once
again. I don't know what kind of impact that'll have on states ... I
suspect they'll work almost as reliably as the SNES does, but I can't
know that until I implement it. It's going to be pretty nasty, though.
¹: this basically removes a lot of unnecessary op. prefixes and the
need to capture `auto& op = operators[index]` at the start of every
function.
I wanted to have subfunctions like
`YM2612::Channel::Operator::Envelope::run()`, etc but unfortunately,
pretty much all of the envelope, phase, pitch, level functions need to
access each other's state.
2017-03-03 10:45:07 +00:00
|
|
|
} operators[4]{*this, *this, *this, *this};
|
|
|
|
|
|
|
|
auto operator[](uint2 index) -> Operator& { return operators[index]; }
|
2017-03-01 20:40:55 +00:00
|
|
|
} channels[6];
|
|
|
|
|
|
|
|
uint16 sine[0x400];
|
|
|
|
int16 pow2[0x200];
|
|
|
|
|
|
|
|
//constants.cpp
|
|
|
|
struct EnvelopeRate {
|
|
|
|
uint32_t divider;
|
|
|
|
uint32_t steps[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint8_t lfoDividers[8];
|
|
|
|
static const uint8_t vibratos[8][16];
|
|
|
|
static const uint8_t tremolos[4];
|
|
|
|
static const uint8_t detunes[3][8];
|
|
|
|
static const EnvelopeRate envelopeRates[16];
|
Update to v100r02 release.
byuu says:
Sigh ... I'm really not a good person. I'm inherently selfish.
My responsibility and obligation right now is to work on loki, and
then on the Tengai Makyou Zero translation, and then on improving the
Famicom emulation.
And yet ... it's not what I really want to do. That shouldn't matter;
I should work on my responsibilities first.
Instead, I'm going to be a greedy, self-centered asshole, and work on
what I really want to instead.
I'm really sorry, guys. I'm sure this will make a few people happy,
and probably upset even more people.
I'm also making zero guarantees that this ever gets finished. As always,
I wish I could keep these things secret, so if I fail / give up, I could
just drop it with no shame. But I would have to cut everyone out of the
WIP process completely to make it happen. So, here goes ...
This WIP adds the initial skeleton for Sega Mega Drive / Genesis
emulation. God help us.
(minor note: apparently the new extension for Mega Drive games is .md,
neat. That's what I chose for the folders too. I thought it was .smd,
so that'll be fixed in icarus for the next WIP.)
(aside: this is why I wanted to get v100 out. I didn't want this code in
a skeleton state in v100's source. Nor did I want really broken emulation,
which the first release is sure to be, tarring said release.)
...
So, basically, I've been ruminating on the legacy I want to leave behind
with higan. 3D systems are just plain out. I'm never going to support
them. They're too complex for my abilities, and they would run too slowly
with my design style. I'm not willing to compromise my design ideals. And
I would never want to play a 3D game system at native 240p/480i resolution
... but 1080p+ upscaling is not accurate, so that's a conflict I want
to avoid entirely. It's also never going to emulate computer systems
(X68K, PC-98, FM-Towns, etc) because holy shit that would completely
destroy me. It's also never going emulate arcade machines.
So I think of higan as a collection of 2D emulators for consoles
and handhelds. I've gone over every major 2D gaming system there is,
looking for ones with games I actually care about and enjoy. And I
basically have five of those systems supported already. Looking at the
remaining list, I see only three systems left that I have any interest
in whatsoever: PC-Engine, Master System, Mega Drive. Again, I'm not in
any way committing to emulating any of these, but ... if I had all of
those in higan, I think I'd be content to really, truly, finally stop
writing more emulators for the rest of my life.
And so I decided to tackle the most difficult system first. If I'm
successful, the Z80 core should cover a lot of the work on the SMS. And
the HuC6280 should land somewhere between the NES and SNES in terms of
difficulty ... closer to the NES.
The systems that just don't appeal to me at all, which I will never touch,
include, but are not limited to:
* Atari 2600/5200/7800
* Lynx
* Jaguar
* Vectrex
* Colecovision
* Commodore 64
* Neo-Geo
* Neo-Geo Pocket / Color
* Virtual Boy
* Super A'can
* 32X
* CD-i
* etc, etc, etc.
And really, even if something were mildly interesting in there ... we
have to stop. I can't scale infinitely. I'm already way past my limit,
but I'm doing this anyway. Too many cores bloats everything and kills
quality on everything. I don't want higan to become MESS v2.
I don't know what I'll do about the Famicom Disk System, PC-Engine CD,
and Mega CD. I don't think I'll be able to achieve 60fps emulating the
Mega CD, even if I tried to.
I don't know what's going to happen here with even the Mega Drive. Maybe
I'll get driven crazy with the documentation and quit. Maybe it'll end
up being too complicated and I'll quit. Maybe the emulation will end up
way too slow and I'll give up. Maybe it'll take me seven years to get
any games playable at all. Maybe Steve Snake, AamirM and Mike Pavone
will pool money to hire a hitman to come after me. Who knows.
But this is what I want to do, so ... here goes nothing.
2016-07-09 04:21:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern YM2612 ym2612;
|