bsnes/higan/md/psg/psg.hpp

48 lines
752 B
C++
Raw Normal View History

//TI SN76489
struct PSG : Thread {
Update to v101r12 release. byuu says: Changelog: - new md/bus/ module for bus reads/writes - abstracts byte/word accesses wherever possible (everything but RAM; forces all but I/O to word, I/O to byte) - holds the system RAM since that's technically not part of the CPU anyway - added md/controller and md/system/peripherals - added emulation of gamepads - added stub PSG audio output (silent) to cap the framerate at 60fps with audio sync enabled - fixed VSRAM reads for plane vertical scrolling (two bugs here: add instead of sub; interlave plane A/B) - mask nametable read offsets (can't exceed 8192-byte nametables apparently) - emulated VRAM/VSRAM/CRAM reads from VDP data port - fixed sprite width/height size calculations - added partial emulation of 40-tile per scanline limitation (enough to fix Sonic's title screen) - fixed off-by-one sprite range testing - fixed sprite tile indexing - Vblank happens at Y=224 with overscan disabled - unsure what happens when you toggle it between Y=224 and Y=240 ... probably bad things - fixed reading of address register for ADDA, CMPA, SUBA - fixed sign extension for MOVEA effect address reads - updated MOVEM to increment the read addresses (but not writeback) for (aN) mode With all of that out of the way, we finally have Sonic the Hedgehog (fully?) playable. I played to stage 1-2 and through the special stage, at least. EDIT: yeah, we probably need HIRQs for Labyrinth Zone. Not much else works, of course. Most games hang waiting on the Z80, and those that don't (like Altered Beast) are still royally screwed. Tons of features still missing; including all of the Z80/PSG/YM2612. A note on the perihperals this time around: the Mega Drive EXT port is basically identical to the regular controller ports. So unlike with the Famicom and Super Famicom, I'm inheriting the exension port from the controller class.
2016-08-21 22:11:24 +00:00
shared_pointer<Emulator::Stream> stream;
static auto Enter() -> void;
auto main() -> void;
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 write(uint8 data) -> void;
Update to v102r10 release. byuu says: Changelog: - removed Emulator::Interface::Capabilities¹ - MS: improved the PSG emulation a bit - MS: added cheat code support - MS: added save state support² - MD: emulated the PSG³ ¹: there's really no point to it anymore. I intend to add cheat codes to the GBA core, as well as both cheat codes and save states to the Mega Drive core. I no longer intend to emulate any new systems, so these values will always be true. Further, the GUI doesn't respond to these values to disable those features anymore ever since the hiro rewrite, so they're double useless. ²: right now, the Z80 core is using a pointer for HL-\>(IX,IY) overrides. But I can't reliably serialize pointers, so I need to convert the Z80 core to use an integer here. The save states still appear to work fine, but there's the potential for an instruction to execute incorrectly if you're incredibly unlucky, so this needs to be fixed as soon as possible. Further, I still need a way to serialize array<T, Size> objects, and I should also add nall::Boolean serialization support. ³: I don't have a system in place to share identical sound chips. But this chip is so incredibly simple that it's not really much trouble to duplicate it. Further, I can strip out the stereo sound support code from the Game Gear portion, so it's even tinier. Note that the Mega Drive only just barely uses the PSG. Not at all in Altered Beast, and only for a tiny part of the BGM music on Sonic 1, plus his jump sound effect.
2017-02-22 21:25:01 +00:00
private:
struct Tone {
//tone.cpp
auto run() -> void;
auto power() -> void;
uint4 volume;
uint10 counter;
uint10 pitch;
uint1 output;
} tone0, tone1, tone2;
struct Noise {
//noise.cpp
auto run() -> void;
auto power() -> void;
uint4 volume;
Update to v102r11 release. byuu says: Changelog: - MD: connected 32KB cartridge RAM up to every Genesis game under 2MB loaded¹ - MS, GG, MD: improved PSG noise channel emulation, hopefully² - MS, GG, MD: lowered PSG volume so that the lowpass doesn't clamp samples³ - MD: added read/write handlers for VRAM, VSRAM, CRAM - MD: block VRAM copy when CD4 is clear⁴ - MD: rewrote VRAM fill, VRAM copy to be byte-based⁵ - MD: VRAM fill byte set should fall through to regular data port write handler⁶ ¹: the header parsing for backup RAM is really weird. It's spaces when not used, and seems to be 0x02000001-0x02003fff for the Shining games. I don't understand why it starts at 0x02000001 instead of 0x02000000. So I'm just forcing every game to have 32KB of RAM for now. There's also special handling for ROMs > 2MB that also have RAM (Phantasy Star IV, etc) where there's a toggle to switch between ROM and RAM. For now, that's not emulated. I was hoping the Shining games would run after this, but they're still dead-locking on me :( ²: Cydrak pointed out some flaws in my attempt to implement what he had. I was having trouble understanding what he meant, so I went back and read the docs on the sound chip and tried implementing the counter the way the docs describe. Hopefully I have this right, but I don't know of any good test ROMs to make sure my noise emulation is correct. The docs say the shifted-out value goes to the output instead of the low bit of the LFSR, so I made that change as well. I think I hear the noise I'm supposed to in Sonic Marble Zone now, but it seems like it's not correct in Green Hill Zone, adding a bit of an annoying buzz to the background music. Maybe it sounds better with the YM2612, but more likely, I still screwed something up :/ ³: it's set to 50% range for both cores right now. For the MD, it will need to be 25% once YM2612 emulation is in. ⁴: technically, this deadlocks the VDP until a hard reset. I could emulate this, but for now I just don't do the VRAM copy in this case. ⁵: VSRAM fill and CRAM fill not supported in this new mode. They're technically undocumented, and I don't have good notes on how they work. I've been seeing conflicting notes on whether the VRAM fill buffer is 8-bits or 16-bits (I chose 8-bits), and on whether you write the low byte and then high byte of each words, or the high byte and then low byte (I chose the latter.) The VRAM copy improvements fix the opening text in Langrisser II, so that's great. ⁶: Langrisser II sets the transfer length to one less than needed to fill the background letter tile on the scenario overview screen. After moving to byte-sized transfers, a black pixel was getting stuck there. So effectively, VRAM fill length becomes DMA length + 1, and the first byte uses the data port so it writes a word value instead of just a byte value. Hopefully this is all correct, although it probably gets way more complicated with the VDP FIFO.
2017-02-25 11:11:46 +00:00
uint10 counter;
uint10 pitch;
Update to v102r10 release. byuu says: Changelog: - removed Emulator::Interface::Capabilities¹ - MS: improved the PSG emulation a bit - MS: added cheat code support - MS: added save state support² - MD: emulated the PSG³ ¹: there's really no point to it anymore. I intend to add cheat codes to the GBA core, as well as both cheat codes and save states to the Mega Drive core. I no longer intend to emulate any new systems, so these values will always be true. Further, the GUI doesn't respond to these values to disable those features anymore ever since the hiro rewrite, so they're double useless. ²: right now, the Z80 core is using a pointer for HL-\>(IX,IY) overrides. But I can't reliably serialize pointers, so I need to convert the Z80 core to use an integer here. The save states still appear to work fine, but there's the potential for an instruction to execute incorrectly if you're incredibly unlucky, so this needs to be fixed as soon as possible. Further, I still need a way to serialize array<T, Size> objects, and I should also add nall::Boolean serialization support. ³: I don't have a system in place to share identical sound chips. But this chip is so incredibly simple that it's not really much trouble to duplicate it. Further, I can strip out the stereo sound support code from the Game Gear portion, so it's even tinier. Note that the Mega Drive only just barely uses the PSG. Not at all in Altered Beast, and only for a tiny part of the BGM music on Sonic 1, plus his jump sound effect.
2017-02-22 21:25:01 +00:00
uint1 enable;
uint2 rate;
uint16 lfsr;
uint1 clock;
uint1 output;
} noise;
uint3 select;
int lowpass;
uint16 levels[16];
};
extern PSG psg;