mirror of https://github.com/bsnes-emu/bsnes.git
240 lines
5.4 KiB
C++
240 lines
5.4 KiB
C++
struct CPU : Processor::WDC65816, Thread, PPUcounter {
|
|
inline auto interruptPending() const -> bool override { return status.interruptPending; }
|
|
inline auto pio() const -> uint8 { return io.pio; }
|
|
inline auto refresh() const -> bool { return status.dramRefresh == 1; }
|
|
inline auto synchronizing() const -> bool override { return scheduler.synchronizing(); }
|
|
|
|
//cpu.cpp
|
|
static auto Enter() -> void;
|
|
auto main() -> void;
|
|
auto load() -> bool;
|
|
auto power(bool reset) -> void;
|
|
|
|
//dma.cpp
|
|
inline auto dmaEnable() -> bool;
|
|
inline auto hdmaEnable() -> bool;
|
|
inline auto hdmaActive() -> bool;
|
|
|
|
auto dmaRun() -> void;
|
|
auto hdmaReset() -> void;
|
|
auto hdmaSetup() -> void;
|
|
auto hdmaRun() -> void;
|
|
|
|
//memory.cpp
|
|
auto idle() -> void override;
|
|
auto read(uint24 addr) -> uint8 override;
|
|
auto write(uint24 addr, uint8 data) -> void override;
|
|
alwaysinline auto wait(uint24 addr) const -> uint;
|
|
auto readDisassembler(uint24 addr) -> uint8 override;
|
|
|
|
//io.cpp
|
|
auto readRAM(uint24 address, uint8 data) -> uint8;
|
|
auto readAPU(uint24 address, uint8 data) -> uint8;
|
|
auto readCPU(uint24 address, uint8 data) -> uint8;
|
|
auto readDMA(uint24 address, uint8 data) -> uint8;
|
|
auto writeRAM(uint24 address, uint8 data) -> void;
|
|
auto writeAPU(uint24 address, uint8 data) -> void;
|
|
auto writeCPU(uint24 address, uint8 data) -> void;
|
|
auto writeDMA(uint24 address, uint8 data) -> void;
|
|
|
|
//timing.cpp
|
|
inline auto dmaClocks() const -> uint;
|
|
inline auto dmaCounter() const -> uint;
|
|
inline auto joypadCounter() 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 joypadEdge() -> 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 Counter {
|
|
uint cpu = 0;
|
|
uint dma = 0;
|
|
} counter;
|
|
|
|
struct Status {
|
|
uint clockCount = 0;
|
|
uint lineClocks = 0;
|
|
|
|
bool irqLock = false;
|
|
|
|
uint dramRefreshPosition = 0;
|
|
uint dramRefresh = 0; //0 = not refreshed; 1 = refresh active; 2 = refresh inactive
|
|
|
|
uint hdmaSetupPosition = 0;
|
|
bool hdmaSetupTriggered = false;
|
|
|
|
uint hdmaPosition = 0;
|
|
bool hdmaTriggered = false;
|
|
|
|
boolean nmiValid;
|
|
boolean nmiLine;
|
|
boolean nmiTransition;
|
|
boolean nmiPending;
|
|
boolean nmiHold;
|
|
|
|
boolean irqValid;
|
|
boolean irqLine;
|
|
boolean irqTransition;
|
|
boolean irqPending;
|
|
boolean irqHold;
|
|
|
|
bool powerPending = false;
|
|
bool resetPending = false;
|
|
|
|
bool interruptPending = false;
|
|
|
|
bool dmaActive = false;
|
|
bool dmaPending = false;
|
|
bool hdmaPending = false;
|
|
bool hdmaMode = 0; //0 = init, 1 = run
|
|
|
|
bool autoJoypadActive = false;
|
|
bool autoJoypadLatch = false;
|
|
uint autoJoypadCounter = 0;
|
|
} status;
|
|
|
|
struct IO {
|
|
//$2181-$2183
|
|
uint17 wramAddress;
|
|
|
|
//$4200
|
|
boolean hirqEnable;
|
|
boolean virqEnable;
|
|
boolean irqEnable;
|
|
boolean nmiEnable;
|
|
boolean autoJoypadPoll;
|
|
|
|
//$4201
|
|
uint8 pio = 0xff;
|
|
|
|
//$4202-$4203
|
|
uint8 wrmpya = 0xff;
|
|
uint8 wrmpyb = 0xff;
|
|
|
|
//$4204-$4206
|
|
uint16 wrdiva = 0xffff;
|
|
uint8 wrdivb = 0xff;
|
|
|
|
//$4207-$420a
|
|
uint12 htime = 0x1ff + 1 << 2;
|
|
uint9 vtime = 0x1ff;
|
|
|
|
//$420d
|
|
uint romSpeed = 8;
|
|
|
|
//$4214-$4217
|
|
uint16 rddiv;
|
|
uint16 rdmpy;
|
|
|
|
//$4218-$421f
|
|
uint16 joy1;
|
|
uint16 joy2;
|
|
uint16 joy3;
|
|
uint16 joy4;
|
|
} io;
|
|
|
|
struct ALU {
|
|
uint mpyctr = 0;
|
|
uint divctr = 0;
|
|
uint shift = 0;
|
|
} alu;
|
|
|
|
struct Channel {
|
|
//dma.cpp
|
|
inline auto step(uint clocks) -> void;
|
|
inline auto edge() -> void;
|
|
|
|
inline auto validA(uint24 address) -> bool;
|
|
inline auto readA(uint24 address) -> uint8;
|
|
inline auto readB(uint8 address, bool valid) -> uint8;
|
|
inline auto writeA(uint24 address, uint8 data) -> void;
|
|
inline auto writeB(uint8 address, uint8 data, bool valid) -> void;
|
|
inline auto transfer(uint24 address, uint2 index) -> void;
|
|
|
|
inline auto dmaRun() -> void;
|
|
inline auto hdmaActive() -> bool;
|
|
inline auto hdmaFinished() -> bool;
|
|
inline auto hdmaReset() -> void;
|
|
inline auto hdmaSetup() -> void;
|
|
inline auto hdmaReload() -> void;
|
|
inline auto hdmaTransfer() -> void;
|
|
inline auto hdmaAdvance() -> void;
|
|
|
|
//$420b
|
|
uint1 dmaEnable;
|
|
|
|
//$420c
|
|
uint1 hdmaEnable;
|
|
|
|
//$43x0
|
|
uint3 transferMode = 7;
|
|
uint1 fixedTransfer = 1;
|
|
uint1 reverseTransfer = 1;
|
|
uint1 unused = 1;
|
|
uint1 indirect = 1;
|
|
uint1 direction = 1;
|
|
|
|
//$43x1
|
|
uint8 targetAddress = 0xff;
|
|
|
|
//$43x2-$43x3
|
|
uint16 sourceAddress = 0xffff;
|
|
|
|
//$43x4
|
|
uint8 sourceBank = 0xff;
|
|
|
|
//$43x5-$43x6
|
|
union {
|
|
uint16 transferSize;
|
|
uint16 indirectAddress;
|
|
};
|
|
|
|
//$43x7
|
|
uint8 indirectBank = 0xff;
|
|
|
|
//$43x8-$43x9
|
|
uint16 hdmaAddress = 0xffff;
|
|
|
|
//$43xa
|
|
uint8 lineCounter = 0xff;
|
|
|
|
//$43xb/$43xf
|
|
uint8 unknown = 0xff;
|
|
|
|
//internal state
|
|
uint1 hdmaCompleted;
|
|
uint1 hdmaDoTransfer;
|
|
|
|
maybe<Channel&> next;
|
|
|
|
Channel() : transferSize(0xffff) {}
|
|
} channels[8];
|
|
};
|
|
|
|
extern CPU cpu;
|