bsnes/higan/sfc/cpu/cpu.hpp
Tim Allen bdc100e123 Update to v102r02 release.
byuu says:

Changelog:

  - I caved on the `samples[] = {0.0}` thing, but I'm very unhappy about it
      - if it's really invalid C++, then GCC needs to stop accepting it
        in strict `-std=c++14` mode
  - Emulator::Interface::Information::resettable is gone
  - Emulator::Interface::reset() is gone
  - FC, SFC, MD cores updated to remove soft reset behavior
  - split GameBoy::Interface into GameBoyInterface,
    GameBoyColorInterface
  - split WonderSwan::Interface into WonderSwanInterface,
    WonderSwanColorInterface
  - PCE: fixed off-by-one scanline error [hex_usr]
  - PCE: temporary hack to prevent crashing when VDS is set to < 2
  - hiro: Cocoa: removed (u)int(#) constants; converted (u)int(#)
    types to (u)int_(#)t types
  - icarus: replaced usage of unique with strip instead (so we don't
    mess up frameworks on macOS)
  - libco: added macOS-specific section marker [Ryphecha]

So ... the major news this time is the removal of the soft reset
behavior. This is a major!! change that results in a 100KiB diff file,
and it's very prone to accidental mistakes!! If anyone is up for
testing, or even better -- looking over the code changes between v102r01
and v102r02 and looking for any issues, please do so. Ideally we'll want
to test every NES mapper type and every SNES coprocessor type by loading
said games and power cycling to make sure the games are all cleanly
resetting. It's too big of a change for me to cover there not being any
issues on my own, but this is truly critical code, so yeah ... please
help if you can.

We technically lose a bit of hardware documentation here. The soft reset
events do all kinds of interesting things in all kinds of different
chips -- or at least they do on the SNES. This is obviously not ideal.
But in the process of removing these portions of code, I found a few
mistakes I had made previously. It simplifies resetting the system state
a lot when not trying to have all the power() functions call the reset()
functions to share partial functionality.

In the future, the goal will be to come up with a way to add back in the
soft reset behavior via keyboard binding as with the Master System core.
What's going to have to happen is that the key binding will have to send
a "reset pulse" to every emulated chip, and those chips are going to
have to act independently to power() instead of reusing functionality.
We'll get there eventually, but there's many things of vastly greater
importance to work on right now, so it'll be a while. The information
isn't lost ... we'll just have to pull it out of v102 when we are ready.

Note that I left the SNES reset vector simulation code in, even though
it's not possible to trigger, for the time being.

Also ... the Super Game Boy core is still disconnected. To be honest, it
totally slipped my mind when I released v102 that it wasn't connected
again yet. This one's going to be pretty tricky to be honest. I'm
thinking about making a third GameBoy::Interface class just for SGB, and
coming up with some way of bypassing platform-> calls when in this
mode.
2017-01-23 08:04:26 +11:00

244 lines
4.8 KiB
C++

struct CPU : Processor::R65816, Thread, PPUcounter {
auto interruptPending() const -> bool override;
auto pio() const -> uint8;
auto joylatch() const -> bool;
CPU();
auto readPort(uint2 port) const -> uint8;
auto writePort(uint2 port, uint8 data) -> void;
static auto Enter() -> void;
auto main() -> void;
auto load(Markup::Node) -> bool;
auto power() -> void;
//dma.cpp
auto dmaStep(uint clocks) -> void;
auto dmaTransferValid(uint8 bbus, uint24 abus) -> bool;
auto dmaAddressValid(uint24 abus) -> bool;
auto dmaRead(uint24 abus) -> uint8;
auto dmaWrite(bool valid, uint addr = 0, uint8 data = 0) -> void;
auto dmaTransfer(bool direction, uint8 bbus, uint24 abus) -> void;
inline auto dmaAddressB(uint n, uint channel) -> uint8;
inline auto dmaAddress(uint n) -> uint24;
inline auto hdmaAddress(uint n) -> uint24;
inline auto hdmaIndirectAddress(uint n) -> uint24;
inline auto dmaEnabledChannels() -> uint;
inline auto hdmaActive(uint n) -> bool;
inline auto hdmaActiveAfter(uint s) -> bool;
inline auto hdmaEnabledChannels() -> uint;
inline auto hdmaActiveChannels() -> uint;
auto dmaRun() -> void;
auto hdmaUpdate(uint n) -> void;
auto hdmaRun() -> void;
auto hdmaInitReset() -> void;
auto hdmaInit() -> void;
//memory.cpp
auto idle() -> void override;
auto read(uint24 addr) -> uint8 override;
auto write(uint24 addr, uint8 data) -> void override;
alwaysinline auto speed(uint24 addr) const -> uint;
auto readDisassembler(uint24 addr) -> uint8 override;
//io.cpp
auto readAPU(uint24 addr, uint8 data) -> uint8;
auto readCPU(uint24 addr, uint8 data) -> uint8;
auto readDMA(uint24 addr, uint8 data) -> uint8;
auto writeAPU(uint24 addr, uint8 data) -> void;
auto writeCPU(uint24 addr, uint8 data) -> void;
auto writeDMA(uint24 addr, uint8 data) -> void;
//timing.cpp
auto dmaCounter() const -> uint;
auto step(uint clocks) -> void;
auto scanline() -> void;
alwaysinline auto aluEdge() -> void;
alwaysinline auto dmaEdge() -> void;
alwaysinline auto lastCycle() -> void;
//irq.cpp
alwaysinline auto pollInterrupts() -> void;
auto nmitimenUpdate(uint8 data) -> void;
auto rdnmi() -> bool;
auto timeup() -> bool;
alwaysinline auto nmiTest() -> bool;
alwaysinline auto irqTest() -> bool;
//joypad.cpp
auto stepAutoJoypadPoll() -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
uint8 wram[128 * 1024];
vector<Thread*> coprocessors;
vector<Thread*> peripherals;
private:
uint version = 2; //allowed: 1, 2
struct Status {
bool interruptPending;
uint clockCount;
uint lineClocks;
//timing
bool irqLock;
uint dramRefreshPosition;
bool dramRefreshed;
uint hdmaInitPosition;
bool hdmaInitTriggered;
uint hdmaPosition;
bool hdmaTriggered;
bool nmiValid;
bool nmiLine;
bool nmiTransition;
bool nmiPending;
bool nmiHold;
bool irqValid;
bool irqLine;
bool irqTransition;
bool irqPending;
bool irqHold;
bool powerPending;
bool resetPending;
//DMA
bool dmaActive;
uint dmaCounter;
uint dmaClocks;
bool dmaPending;
bool hdmaPending;
bool hdmaMode; //0 = init, 1 = run
//auto joypad polling
bool autoJoypadActive;
bool autoJoypadLatch;
uint autoJoypadCounter;
uint autoJoypadClock;
} status;
struct IO {
//$2140-217f
uint8 port[4];
//$2181-$2183
uint17 wramAddress;
//$4016-$4017
bool joypadStrobeLatch;
//$4200
bool nmiEnabled;
bool hirqEnabled;
bool virqEnabled;
bool autoJoypadPoll;
//$4201
uint8 pio;
//$4202-$4203
uint8 wrmpya;
uint8 wrmpyb;
//$4204-$4206
uint16 wrdiva;
uint8 wrdivb;
//$4207-$420a
uint9 hirqPos;
uint9 virqPos;
//$420d
uint romSpeed;
//$4214-$4217
uint16 rddiv;
uint16 rdmpy;
//$4218-$421f
uint16 joy1;
uint16 joy2;
uint16 joy3;
uint16 joy4;
} io;
struct ALU {
uint mpyctr;
uint divctr;
uint shift;
} alu;
struct Channel {
//$420b
bool dmaEnabled;
//$420c
bool hdmaEnabled;
//$43x0
bool direction;
bool indirect;
bool unused;
bool reverseTransfer;
bool fixedTransfer;
uint3 transferMode;
//$43x1
uint8 targetAddress;
//$43x2-$43x3
uint16 sourceAddress;
//$43x4
uint8 sourceBank;
//$43x5-$43x6
union {
uint16 transferSize;
uint16 indirectAddress;
};
//$43x7
uint8 indirectBank;
//$43x8-$43x9
uint16 hdmaAddress;
//$43xa
uint8 lineCounter;
//$43xb/$43xf
uint8 unknown;
//internal state
bool hdmaCompleted;
bool hdmaDoTransfer;
Channel() : transferSize(0) {}
} channel[8];
struct Pipe {
bool valid;
uint addr;
uint8 data;
} pipe;
};
extern CPU cpu;