//----------------------------------------------------------------------------
//
// File:		ti994a.hpp
// Date:		23-Feb-1998
// Programmer:	Marc Rousseau
//
// Description:
//
// Copyright (c) 1998-2004 Marc Rousseau, All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
//
// Revision History:
//
//----------------------------------------------------------------------------

#ifndef TI994A_HPP_
#define TI994A_HPP_

#include "cBaseObject.hpp"
#include "icomputer.hpp"
#include "tms9900.hpp"

const int CPU_SPEED_HZ = 3000000;

struct sMemoryRegion;

struct iTMS9900;
struct iTMS9901;
struct iTMS9918A;
struct iTMS9919;
struct iTMS5220;

struct iCartridge;

enum HEADER_SECTION_E
{
	SECTION_BASE,
	SECTION_CPU,
	SECTION_VDP,
	SECTION_GROM,
	SECTION_ROM,
	SECTION_SOUND,
	SECTION_SPEECH,
	SECTION_CRU,
	SECTION_DSR
};

struct sStateHeader
{
	UINT16          id;
	UINT16          length;
};

struct sStateHeaderInfo
{
	sStateHeader    header;
	UINT32          offset;
};

struct sImageFileState
{
	FILE           *file;
	long            start;
	long            next;
};

class cTI994A :
	public virtual cBaseObject,
	public virtual iComputer
{
protected:

	enum TRAP_TYPE_E
	{
		TRAP_BANK_SWITCH,
		TRAP_SCRATCH_PAD,
		TRAP_SOUND,
		TRAP_SPEECH,
		TRAP_VIDEO,
		TRAP_GROM
	};

	cRefPtr<iTMS9900>   m_CPU;
	cRefPtr<iTMS9901>   m_PIC;
	cRefPtr<iTMS9918A>  m_VDP;
	cRefPtr<iTMS9919>   m_SoundGenerator;
	cRefPtr<iTMS5220>   m_SpeechSynthesizer;

	UINT32              m_RetraceInterval;
	UINT32              m_LastRetrace;

	cRefPtr<iCartridge> m_Console;
	cRefPtr<iCartridge> m_Cartridge;

	UINT16              m_ActiveCRU;
	cRefPtr<iDevice>    m_Device[ 32 ];

	UINT8              *m_GromPtr;
	ADDRESS             m_GromAddress;
	ADDRESS             m_GromLastInstruction;
	int                 m_GromReadShift;
	int                 m_GromWriteShift;
	int                 m_GromCounter;

	sMemoryRegion      *m_CpuMemoryInfo[ 16 ];	// Pointers 4K banks of CPU RAM
	sMemoryRegion      *m_GromMemoryInfo[ 8 ];	// Pointers 8K banks of Graphics RAM

	UINT8              *m_CpuMemory;			// Pointer to 64K of System ROM/RAM
	UINT8              *m_GromMemory;			// Pointer to 64K of Graphics ROM/RAM
	UINT8              *m_VideoMemory;			// Pointer to 16K of Video RAM

public:

	cTI994A( iCartridge *, iTMS9918A * = nullptr, iTMS9919 * = nullptr, iTMS5220 * = nullptr );

	// iBaseObject Methods
	virtual const void *GetInterface( const std::string &name ) const override;

	// iComputer Methods
	virtual iTMS9900 *GetCPU( ) const override;
	virtual iTMS9918A *GetVDP( ) const override;
	virtual iTMS9919 *GetSoundGenerator( ) const override;
	virtual iTMS5220 *GetSynthesizer( ) const override;
	virtual UINT8 *GetCpuMemory( ) const override;
	virtual UINT8 *GetGromMemory( ) const override;
	virtual UINT8 *GetVideoMemory( ) const override;
	virtual void SetGromAddress( UINT16 addr ) override;
	virtual UINT16 GetGromAddress( ) const override;
	virtual int ReadCRU( UINT16 ) override;
	virtual void WriteCRU( UINT16, UINT16 ) override;
	virtual void AddDevice( iDevice * ) override;
	virtual void InsertCartridge( iCartridge *, bool = true ) override;
	virtual void RemoveCartridge( iCartridge *, bool = true ) override;
	virtual void Reset( ) override;
	virtual void Sleep( int, UINT32 ) override;
	virtual void WakeCPU( UINT32 ) override;
	virtual void Run( ) override;
	virtual void Stop( ) override;
	virtual bool Step( ) override;
	virtual bool IsRunning( ) override;
	virtual bool SaveImage( const char * ) override;
	virtual bool LoadImage( const char * ) override;

	static bool OpenImageFile( const char *, sImageFileState * );
	static bool FindHeader( sImageFileState *, HEADER_SECTION_E );
	static void MarkHeader( FILE *, HEADER_SECTION_E, sStateHeaderInfo * );
	static bool SaveHeader( FILE *, sStateHeaderInfo * );

protected:

	iDevice *GetDevice( ADDRESS ) const;

	static void _TimerHookProc( );
	virtual void TimerHookProc( UINT32 );
	virtual bool VideoRetrace( );

	static UINT8 TrapFunction( void *, int, bool, ADDRESS, UINT8 );

	virtual UINT8 BankSwitch           ( ADDRESS, UINT8 );
	virtual UINT8 SoundBreakPoint      ( ADDRESS, UINT8 );
	virtual UINT8 SpeechWriteBreakPoint( ADDRESS, UINT8 );
	virtual UINT8 SpeechReadBreakPoint ( ADDRESS, UINT8 );
	virtual UINT8 VideoWriteBreakPoint ( ADDRESS, UINT8 );
	virtual UINT8 VideoReadBreakPoint  ( ADDRESS, UINT8 );
	virtual UINT8 GromWriteBreakPoint  ( ADDRESS, UINT8 );
	virtual UINT8 GromReadBreakPoint   ( ADDRESS, UINT8 );

protected:

	virtual ~cTI994A( );

private:

	cTI994A( const cTI994A & ) = delete;				// no implementation
	cTI994A & operator =( const cTI994A & ) = delete;	// no implementation

};

#endif
