2016-02-02 10:51:17 +00:00
|
|
|
#pragma once
|
2012-04-29 06:16:44 +00:00
|
|
|
|
|
|
|
namespace Processor {
|
|
|
|
|
|
|
|
struct GSU {
|
|
|
|
#include "registers.hpp"
|
|
|
|
|
Update to v098r13 release.
byuu says:
Changelog:
- nall/dsp returns with new iir/biquad.hpp and resampler/cubic.hpp files
- nall/queue.hpp added (simple ring buffer ... nall/vector wouldn't
cause too many moves with FIFO)
- audio streams now only buffer 20ms; so even if multiple audio streams
desync, latency can never exceed 20ms
- replaced blackman windwed sinc FIR hermite audio filter with transposed
direct form II biquadratic sixth-order IIR butterworth filter (better
attenuation of frequencies above 20KHz, faster, no need for decimation,
less code)
- put in experimental eight-tap echo filter (a lot better than what I
had before, but still rather weak)
- substantial cleanups to the SuperFX GSU processor core (slightly
faster, 479KB->100KB object file, 42.7KB->33.4KB source code size,
way less code duplication)
We'll definitely want to test the whole SuperFX library (not many games)
just to make sure there's no regressions caused by this one.
Not sure what I want to do with audio processing effects yet. I've always
really wanted lots of fun controls to customize audio, and now finally
with this new biquad filter, I can finally start implementing real
effects. For instance, an equalizer wouldn't be too complicated anymore.
The new reverb effect is still a poor man's version. I need to find human
readable source for implementing a comb-filter properly. I'm pretty sure
I can already treat nall::queue as an all-pass filter since all that
does is phase shift (fancy audio term for "delay audio"). What's really
going to be hard is figuring out how to expose user-friendly settings for
controlling it. It looks like you need a bunch of coprime coefficients,
and I don't think casual users are going to be able to hand-enter coprime
values to get the echo effect they want. I uh ... don't even know how
to calculate coprime values dynamically right now >_> But we're going
to have to, as they are correlated to the output sampling rate.
We'll definitely want to make some audio profiles so that users can
quickly select pre-configured themes that sound nice, but expose the
underlying coefficients so that they can tweak stuff to their liking. This
isn't just about higan, this is about me trying to learn digital signal
processing, so please don't be too upset about feature creep or anything
on this.
Anyway ... I'm having some difficulties with my audio right now. When
the reverb effect is enabled, there's a bunch of static on system
reset for just a moment. But this should not be possible. nall::queue
is initializing all previous reverb sample elements to 0.0. I don't
understand where static is coming in from. Further, we have the same
issue with both the windowed sinc and the biquad filters ... a bit of
a popping sound when starting a game. Any help tracking this down would
be appreciated.
There's also one really annoying issue ... I can't seem to do reverb
or volume adjustments with normalized samples. If I say "volume *= 0.5"
in higan/audio/audio.cpp line 68, it doesn't just halve the volume, it
adds a whole bunch of distortion. This makes absolutely zero sense to
me. The sample values are between 0.0 (mute) and 1.0 (full volume) here,
so multiplying a double by 0.5 shouldn't cause distortion. So right now,
I'm doing these adjustments with less precision after denormalizing back
to int16. Anyone ever see something like that? :/
2016-05-31 22:29:36 +00:00
|
|
|
virtual auto step(uint clocks) -> void = 0;
|
2012-04-29 06:16:44 +00:00
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
virtual auto stop() -> void = 0;
|
|
|
|
virtual auto color(uint8 source) -> uint8 = 0;
|
|
|
|
virtual auto plot(uint8 x, uint8 y) -> void = 0;
|
|
|
|
virtual auto rpix(uint8 x, uint8 y) -> uint8 = 0;
|
2012-04-29 06:16:44 +00:00
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
virtual auto pipe() -> uint8 = 0;
|
2016-06-05 22:10:01 +00:00
|
|
|
virtual auto syncROMBuffer() -> void = 0;
|
|
|
|
virtual auto readROMBuffer() -> uint8 = 0;
|
|
|
|
virtual auto syncRAMBuffer() -> void = 0;
|
|
|
|
virtual auto readRAMBuffer(uint16 addr) -> uint8 = 0;
|
|
|
|
virtual auto writeRAMBuffer(uint16 addr, uint8 data) -> void = 0;
|
|
|
|
virtual auto flushCache() -> void = 0;
|
2012-04-29 06:16:44 +00:00
|
|
|
|
2016-06-05 22:10:01 +00:00
|
|
|
virtual auto read(uint24 addr, uint8 data = 0x00) -> uint8 = 0;
|
|
|
|
virtual auto write(uint24 addr, uint8 data) -> void = 0;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
2015-06-27 02:38:47 +00:00
|
|
|
//gsu.cpp
|
|
|
|
auto power() -> void;
|
2012-04-29 06:16:44 +00:00
|
|
|
|
|
|
|
//instructions.cpp
|
Update to v102r27 release.
byuu says:
Changelog:
- processor/gsu: minor code cleanup
- processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
- processor/lr35902: minor code cleanup
- processor/spc700: completed code cleanup (sans disassembler)
- no longer uses internal global state inside instructions
- processor/spc700: will no longer hang the emulator if stuck in a WAI
(SLEEP) or STP (STOP) instruction
- processor/spc700: fixed bug in handling of OR1 and AND1 instructions
- processor/z80: minor code cleanup
- sfc/dsp: revert to initializing registers to 0x00; save for
ENDX=random(), FLG=0xe0 [Jonas Quinn]
Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.
We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.
Thanks again to Jonas Quinn for the continued research into this issue.
EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.
The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.
So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
2017-06-19 02:07:54 +00:00
|
|
|
auto instructionADD_ADC(uint n) -> void;
|
|
|
|
auto instructionALT1() -> void;
|
|
|
|
auto instructionALT2() -> void;
|
|
|
|
auto instructionALT3() -> void;
|
|
|
|
auto instructionAND_BIC(uint n) -> void;
|
|
|
|
auto instructionASR_DIV2() -> void;
|
|
|
|
auto instructionBranch(bool c) -> void;
|
|
|
|
auto instructionCACHE() -> void;
|
|
|
|
auto instructionCOLOR_CMODE() -> void;
|
|
|
|
auto instructionDEC(uint n) -> void;
|
|
|
|
auto instructionFMULT_LMULT() -> void;
|
|
|
|
auto instructionFROM_MOVES(uint n) -> void;
|
|
|
|
auto instructionGETB() -> void;
|
|
|
|
auto instructionGETC_RAMB_ROMB() -> void;
|
|
|
|
auto instructionHIB() -> void;
|
|
|
|
auto instructionIBT_LMS_SMS(uint n) -> void;
|
|
|
|
auto instructionINC(uint n) -> void;
|
|
|
|
auto instructionIWT_LM_SM(uint n) -> void;
|
|
|
|
auto instructionJMP_LJMP(uint n) -> void;
|
|
|
|
auto instructionLINK(uint n) -> void;
|
|
|
|
auto instructionLoad(uint n) -> void;
|
|
|
|
auto instructionLOB() -> void;
|
|
|
|
auto instructionLOOP() -> void;
|
|
|
|
auto instructionLSR() -> void;
|
|
|
|
auto instructionMERGE() -> void;
|
|
|
|
auto instructionMULT_UMULT(uint n) -> void;
|
|
|
|
auto instructionNOP() -> void;
|
|
|
|
auto instructionNOT() -> void;
|
|
|
|
auto instructionOR_XOR(uint n) -> void;
|
|
|
|
auto instructionPLOT_RPIX() -> void;
|
|
|
|
auto instructionROL() -> void;
|
|
|
|
auto instructionROR() -> void;
|
|
|
|
auto instructionSBK() -> void;
|
|
|
|
auto instructionSEX() -> void;
|
|
|
|
auto instructionStore(uint n) -> void;
|
|
|
|
auto instructionSTOP() -> void;
|
|
|
|
auto instructionSUB_SBC_CMP(uint n) -> void;
|
|
|
|
auto instructionSWAP() -> void;
|
|
|
|
auto instructionTO_MOVE(uint n) -> void;
|
|
|
|
auto instructionWITH(uint n) -> void;
|
2015-06-27 02:38:47 +00:00
|
|
|
|
Update to v098r13 release.
byuu says:
Changelog:
- nall/dsp returns with new iir/biquad.hpp and resampler/cubic.hpp files
- nall/queue.hpp added (simple ring buffer ... nall/vector wouldn't
cause too many moves with FIFO)
- audio streams now only buffer 20ms; so even if multiple audio streams
desync, latency can never exceed 20ms
- replaced blackman windwed sinc FIR hermite audio filter with transposed
direct form II biquadratic sixth-order IIR butterworth filter (better
attenuation of frequencies above 20KHz, faster, no need for decimation,
less code)
- put in experimental eight-tap echo filter (a lot better than what I
had before, but still rather weak)
- substantial cleanups to the SuperFX GSU processor core (slightly
faster, 479KB->100KB object file, 42.7KB->33.4KB source code size,
way less code duplication)
We'll definitely want to test the whole SuperFX library (not many games)
just to make sure there's no regressions caused by this one.
Not sure what I want to do with audio processing effects yet. I've always
really wanted lots of fun controls to customize audio, and now finally
with this new biquad filter, I can finally start implementing real
effects. For instance, an equalizer wouldn't be too complicated anymore.
The new reverb effect is still a poor man's version. I need to find human
readable source for implementing a comb-filter properly. I'm pretty sure
I can already treat nall::queue as an all-pass filter since all that
does is phase shift (fancy audio term for "delay audio"). What's really
going to be hard is figuring out how to expose user-friendly settings for
controlling it. It looks like you need a bunch of coprime coefficients,
and I don't think casual users are going to be able to hand-enter coprime
values to get the echo effect they want. I uh ... don't even know how
to calculate coprime values dynamically right now >_> But we're going
to have to, as they are correlated to the output sampling rate.
We'll definitely want to make some audio profiles so that users can
quickly select pre-configured themes that sound nice, but expose the
underlying coefficients so that they can tweak stuff to their liking. This
isn't just about higan, this is about me trying to learn digital signal
processing, so please don't be too upset about feature creep or anything
on this.
Anyway ... I'm having some difficulties with my audio right now. When
the reverb effect is enabled, there's a bunch of static on system
reset for just a moment. But this should not be possible. nall::queue
is initializing all previous reverb sample elements to 0.0. I don't
understand where static is coming in from. Further, we have the same
issue with both the windowed sinc and the biquad filters ... a bit of
a popping sound when starting a game. Any help tracking this down would
be appreciated.
There's also one really annoying issue ... I can't seem to do reverb
or volume adjustments with normalized samples. If I say "volume *= 0.5"
in higan/audio/audio.cpp line 68, it doesn't just halve the volume, it
adds a whole bunch of distortion. This makes absolutely zero sense to
me. The sample values are between 0.0 (mute) and 1.0 (full volume) here,
so multiplying a double by 0.5 shouldn't cause distortion. So right now,
I'm doing these adjustments with less precision after denormalizing back
to int16. Anyone ever see something like that? :/
2016-05-31 22:29:36 +00:00
|
|
|
//switch.cpp
|
|
|
|
auto instruction(uint8 opcode) -> void;
|
2015-06-27 02:38:47 +00:00
|
|
|
|
|
|
|
//serialization.cpp
|
|
|
|
auto serialize(serializer&) -> void;
|
2016-03-26 01:56:15 +00:00
|
|
|
|
|
|
|
//disassembler.cpp
|
2016-06-05 22:10:01 +00:00
|
|
|
auto disassembleOpcode(char* output) -> void;
|
Update to v102r27 release.
byuu says:
Changelog:
- processor/gsu: minor code cleanup
- processor/hg51b: renamed reg(Read,Write) to register(Read,Write)
- processor/lr35902: minor code cleanup
- processor/spc700: completed code cleanup (sans disassembler)
- no longer uses internal global state inside instructions
- processor/spc700: will no longer hang the emulator if stuck in a WAI
(SLEEP) or STP (STOP) instruction
- processor/spc700: fixed bug in handling of OR1 and AND1 instructions
- processor/z80: minor code cleanup
- sfc/dsp: revert to initializing registers to 0x00; save for
ENDX=random(), FLG=0xe0 [Jonas Quinn]
Major testing of the SNES game library would be appreciated, now that
its CPU cores have all been revised.
We know the DSP registers read back as randomized data ... mostly, but
there are apparently internal latches, which we can't emulate with the
current DSP design. So until we know which registers have separate
internal state that actually *is* initialized, I'm going to play it safe
and not break more games.
Thanks again to Jonas Quinn for the continued research into this issue.
EDIT: that said ... `MD works if((ENDX&0x30) > 0)` is only a 3:4 chance
that the game will work. That seems pretty unlikely that the odds of it
working are that low, given hardware testing by others in the past :/ I
thought if worked if `PITCH != 0` before, which would have been way more
likely.
The two remaining CPU cores that need major cleanup efforts are the
LR35902 and ARM cores. Both are very large, complicated, annoying cores
that will probably be better off as full rewrites from scratch. I don't
think I want to delay v103 in trying to accomplish that, however.
So I think it'll be best to focus on allowing the Mega Drive core to not
lock when processors are frozen waiting on a response from other
processors during a save state operation. Then we should be good for a
new release.
2017-06-19 02:07:54 +00:00
|
|
|
auto disassembleALT0(char* output) -> void;
|
|
|
|
auto disassembleALT1(char* output) -> void;
|
|
|
|
auto disassembleALT2(char* output) -> void;
|
|
|
|
auto disassembleALT3(char* output) -> void;
|
2012-04-29 06:16:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|