#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 _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 void SET1(); template void CLR1(); template void BBS(); template void BBC(); //Subroutine operations void PCALL(); void JSR(); void RTS(); void BRK(); void RTI(); template 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