351 lines
No EOL
6.4 KiB
C++
351 lines
No EOL
6.4 KiB
C++
#if (defined(DUMMYSPC) && !defined(__DUMMYSPC__H)) || (!defined(DUMMYSPC) && !defined(__SPC__H))
|
|
#ifdef DUMMYSPC
|
|
#define __DUMMYSPC__H
|
|
#else
|
|
#define __SPC__H
|
|
#endif
|
|
|
|
#include "stdafx.h"
|
|
#include "SpcTypes.h"
|
|
#include "CpuTypes.h"
|
|
#include "DebugTypes.h"
|
|
#include "SpcTimer.h"
|
|
#include "../Utilities/ISerializable.h"
|
|
|
|
class Console;
|
|
class MemoryManager;
|
|
class SpcFileData;
|
|
class SPC_DSP;
|
|
struct AddressInfo;
|
|
|
|
class Spc : public ISerializable
|
|
{
|
|
public:
|
|
static constexpr int SpcRamSize = 0x10000;
|
|
static constexpr int SpcRomSize = 0x40;
|
|
static constexpr int SpcSampleRate = 32040;
|
|
|
|
private:
|
|
static constexpr int SampleBufferSize = 0x20000;
|
|
static constexpr uint16_t ResetVector = 0xFFFE;
|
|
|
|
Console* _console;
|
|
MemoryManager* _memoryManager;
|
|
unique_ptr<SPC_DSP> _dsp;
|
|
|
|
double _clockRatio;
|
|
|
|
/* Temporary data used in the middle of operations */
|
|
uint16_t _operandA;
|
|
uint16_t _operandB;
|
|
uint16_t _tmp1;
|
|
uint16_t _tmp2;
|
|
uint16_t _tmp3;
|
|
uint8_t _opCode;
|
|
SpcOpStep _opStep;
|
|
uint8_t _opSubStep;
|
|
|
|
bool _enabled;
|
|
|
|
SpcState _state;
|
|
uint8_t* _ram;
|
|
uint8_t _spcBios[64] {
|
|
0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0,
|
|
0xFC, 0x8F, 0xAA, 0xF4, 0x8F, 0xBB, 0xF5, 0x78,
|
|
0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4,
|
|
0xD0, 0xFC, 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5,
|
|
0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, 0xAB,
|
|
0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA,
|
|
0xF6, 0xDA, 0x00, 0xBA, 0xF4, 0xC4, 0xF4, 0xDD,
|
|
0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF
|
|
};
|
|
|
|
int16_t *_soundBuffer;
|
|
|
|
//Store operations
|
|
void STA();
|
|
void STX();
|
|
void STY();
|
|
void STW();
|
|
|
|
void STA_AutoIncX();
|
|
void LDA_AutoIncX();
|
|
|
|
//Load operations
|
|
void LDA();
|
|
void LDA_Imm();
|
|
void LDX();
|
|
void LDX_Imm();
|
|
void LDY();
|
|
void LDY_Imm();
|
|
void LDW();
|
|
|
|
//Transfer
|
|
void Transfer(uint8_t & dst, uint8_t src);
|
|
void TXA();
|
|
void TYA();
|
|
void TAX();
|
|
void TAY();
|
|
void TSX();
|
|
void TXS();
|
|
|
|
void STC();
|
|
void LDC();
|
|
void MOV();
|
|
void MOV_Imm();
|
|
|
|
//Arithmetic
|
|
uint8_t Add(uint8_t a, uint8_t b);
|
|
uint8_t Sub(uint8_t a, uint8_t b);
|
|
|
|
void ADC();
|
|
void ADC_Acc();
|
|
void ADC_Imm();
|
|
void ADDW();
|
|
void SBC();
|
|
void SBC_Acc();
|
|
void SBC_Imm();
|
|
void SUBW();
|
|
|
|
void Compare(uint8_t a, uint8_t b);
|
|
void CMP();
|
|
void CMP_Acc();
|
|
void CMP_Imm();
|
|
void CPX();
|
|
void CPX_Imm();
|
|
void CPY();
|
|
void CPY_Imm();
|
|
void CMPW();
|
|
|
|
//Increment/decrement
|
|
void INC();
|
|
void INC_Acc();
|
|
void INX();
|
|
void INY();
|
|
void INCW();
|
|
|
|
void DEC();
|
|
void DEC_Acc();
|
|
void DEX();
|
|
void DEY();
|
|
void DECW();
|
|
|
|
void MUL();
|
|
void DIV();
|
|
|
|
//Decimal
|
|
void DAA();
|
|
void DAS();
|
|
|
|
//Logical
|
|
void AND();
|
|
void AND_Acc();
|
|
void AND_Imm();
|
|
void OR();
|
|
void OR_Acc();
|
|
void OR_Imm();
|
|
void EOR();
|
|
void EOR_Acc();
|
|
void EOR_Imm();
|
|
|
|
void SetCarry(uint8_t carry);
|
|
void OR1();
|
|
void NOR1();
|
|
void AND1();
|
|
void NAND1();
|
|
void EOR1();
|
|
void NOT1();
|
|
|
|
//Shift/rotate
|
|
uint8_t ShiftLeft(uint8_t value);
|
|
uint8_t RollLeft(uint8_t value);
|
|
uint8_t ShiftRight(uint8_t value);
|
|
uint8_t RollRight(uint8_t value);
|
|
|
|
void ASL();
|
|
void ASL_Acc();
|
|
void LSR();
|
|
void LSR_Acc();
|
|
void ROL();
|
|
void ROL_Acc();
|
|
void ROR();
|
|
void ROR_Acc();
|
|
void XCN();
|
|
|
|
//Branch operations
|
|
void Branch();
|
|
void BRA();
|
|
void BEQ();
|
|
void BNE();
|
|
void BCS();
|
|
void BCC();
|
|
void BVS();
|
|
void BVC();
|
|
void BMI();
|
|
void BPL();
|
|
void BBS();
|
|
void BBC();
|
|
void CBNE();
|
|
void DBNZ();
|
|
void DBNZ_Y();
|
|
void JMP();
|
|
|
|
//Flag operations
|
|
void CLRC();
|
|
void SETC();
|
|
void NOTC();
|
|
void CLRV();
|
|
void CLRP();
|
|
void SETP();
|
|
void EI();
|
|
void DI();
|
|
|
|
void TSET1();
|
|
void TCLR1();
|
|
|
|
template<uint8_t bit> void SET1();
|
|
template<uint8_t bit> void CLR1();
|
|
template<uint8_t bit> void BBS();
|
|
template<uint8_t bit> void BBC();
|
|
|
|
//Subroutine operations
|
|
void PCALL();
|
|
void JSR();
|
|
void RTS();
|
|
void BRK();
|
|
void RTI();
|
|
|
|
template<uint8_t offset> void TCALL();
|
|
|
|
//Stack operations
|
|
void PushOperation(uint8_t value);
|
|
void PullOperation(uint8_t & dst);
|
|
|
|
void PHA();
|
|
void PHX();
|
|
void PHY();
|
|
void PHP();
|
|
|
|
void PLA();
|
|
void PLX();
|
|
void PLY();
|
|
void PLP();
|
|
|
|
//Other operations
|
|
void NOP();
|
|
void SLEEP();
|
|
void STOP();
|
|
|
|
void Idle();
|
|
void DummyRead();
|
|
void DummyRead(uint16_t addr);
|
|
uint8_t Read(uint16_t addr, MemoryOperationType type = MemoryOperationType::Read);
|
|
uint16_t ReadWord(uint16_t addr, MemoryOperationType type = MemoryOperationType::Read);
|
|
void Write(uint16_t addr, uint8_t value, MemoryOperationType type = MemoryOperationType::Write);
|
|
|
|
void Addr_Dir();
|
|
void Addr_DirIdxX();
|
|
void Addr_DirIdxY();
|
|
void Addr_DirToDir();
|
|
void Addr_DirImm();
|
|
void Addr_IndX();
|
|
void Addr_IndXToIndY();
|
|
void Addr_Abs();
|
|
void Addr_AbsBit();
|
|
void Addr_AbsIdxX();
|
|
void Addr_AbsIdxY();
|
|
void Addr_AbsIdxXInd();
|
|
void Addr_DirIdxXInd();
|
|
void Addr_DirIndIdxY();
|
|
void Addr_Rel();
|
|
void Addr_Imm();
|
|
|
|
void ClearFlags(uint8_t flags);
|
|
void SetFlags(uint8_t flags);
|
|
bool CheckFlag(uint8_t flag);
|
|
void SetZeroNegativeFlags(uint8_t value);
|
|
void SetZeroNegativeFlags16(uint16_t value);
|
|
|
|
uint8_t GetByteValue();
|
|
|
|
void Push(uint8_t value);
|
|
uint8_t Pop();
|
|
|
|
uint16_t GetDirectAddress(uint8_t offset);
|
|
|
|
uint8_t GetOpCode();
|
|
uint8_t ReadOperandByte();
|
|
|
|
void IncCycleCount(int32_t addr);
|
|
void EndOp();
|
|
void EndAddr();
|
|
void ProcessCycle();
|
|
void Exec();
|
|
|
|
void UpdateClockRatio();
|
|
|
|
public:
|
|
Spc(Console* console);
|
|
virtual ~Spc();
|
|
|
|
void SetSpcState(bool enabled);
|
|
|
|
void Run();
|
|
void Reset();
|
|
|
|
uint8_t DebugRead(uint16_t addr);
|
|
void DebugWrite(uint16_t addr, uint8_t value);
|
|
|
|
uint8_t CpuReadRegister(uint16_t addr);
|
|
void CpuWriteRegister(uint32_t addr, uint8_t value);
|
|
|
|
uint8_t DspReadRam(uint16_t addr);
|
|
void DspWriteRam(uint16_t addr, uint8_t value);
|
|
|
|
void ProcessEndFrame();
|
|
|
|
SpcState GetState();
|
|
DspState GetDspState();
|
|
|
|
bool IsMuted();
|
|
AddressInfo GetAbsoluteAddress(uint16_t addr);
|
|
int GetRelativeAddress(AddressInfo & absAddress);
|
|
|
|
uint8_t* GetSpcRam();
|
|
uint8_t* GetSpcRom();
|
|
|
|
void LoadSpcFile(SpcFileData* spcData);
|
|
|
|
void Serialize(Serializer &s) override;
|
|
|
|
void SetReg(SpcRegister reg, uint16_t value);
|
|
|
|
#ifdef DUMMYSPC
|
|
private:
|
|
uint32_t _writeCounter = 0;
|
|
uint32_t _writeAddresses[10];
|
|
uint8_t _writeValue[10];
|
|
|
|
uint32_t _readCounter = 0;
|
|
uint32_t _readAddresses[10];
|
|
uint8_t _readValue[10];
|
|
|
|
void LogRead(uint32_t addr, uint8_t value);
|
|
void LogWrite(uint32_t addr, uint8_t value);
|
|
|
|
public:
|
|
DummySpc(uint8_t *spcRam, SpcState &state);
|
|
|
|
void Step();
|
|
|
|
void SetDummyState(SpcState &state);
|
|
int32_t GetLastOperand();
|
|
|
|
uint32_t GetWriteCount();
|
|
uint32_t GetReadCount();
|
|
void GetWriteInfo(uint32_t index, uint32_t &addr, uint8_t &value);
|
|
void GetReadInfo(uint32_t index, uint32_t &addr, uint8_t &value);
|
|
#endif
|
|
};
|
|
|
|
#endif |