// ###########################################################################
// #
// # OSCAVideo - Implementation of OSCA Video Module
// # Copyright (C) 2009 Tony Friery [DialTone]
// #
// # ALL RIGHTS RESERVED
// #
// ###########################################################################

#ifndef OSCAVideoH
#define OSCAVideoH

#include "z80.h"
#include "GR32.hpp"

///////////////////////////////////////////////////////////////////////
//
//		Definition of Video Module Types and Constants
//
///////////////////////////////////////////////////////////////////////

typedef enum
{
	VIDEO_PAL_P,		// PAL, Non-Interlaced
	VIDEO_PAL_I,		// PAL, Interlaced
	VIDEO_NTSC_P,		// NTSC, Progressive
	VIDEO_NTSC_I,		// NTSC, Interlaced
	VIDEO_VGA			// VGA
} VideoSystem;

typedef enum
{
	BITMAP_PLANAR,		// Planar Bitmap Mode
	BITMAP_CHUNKY,		// Chunky Bitmap Mode
	TILE_MAP				// Tilemap Mode (Legacy or Extended)
} DisplayMode;

typedef enum
{
	TILE_LEGACY,		// Legacy tilemap mode
	TILE_EXTENDED		// Extended tilemap mode
} TileMapMode;

typedef struct
{
	word		DefNum;	// Definition Number
	word		X;			// X Co-Ordinate
	word 		Y;			// Y Co-Ordinate
	byte		Height;	// Height
	bool		Mirror;	// X-Mirrored
	bool		InFront;	// Interleave in front
	bool		Matte;	// Use Matte Colours
} SpriteRegister;


///////////////////////////////////////////////////////////////////////
//
//		Definition of Video Module Class
//
///////////////////////////////////////////////////////////////////////

class TOSCABoard;

class TOSCAVideo
{
	private:
		TOSCABoard				*m_pOwner;						// Pointer to owning board (for linecop)
		VideoSystem				CurrentVidSystem;				// Current Video Type (PAL/NTSC/VGA)
		DisplayMode				CurrentVidMode;				// Mode (Planar/Chunky/Tilemap)
		TileMapMode				CurrentTileMode;				// Tilemap mode (Legacy/Extended)

		byte  					PaletteRAM[2][512];			// 2x 256 Palette Entries (12-bit)
		byte						VideoRAM[(512 * 1024)];		// 512K Video RAM
		byte 						SpriteRAM[(128 * 1024)];	// 128K Sprite RAM

		int						fScanPrescaler;				// Prescaler for Scanline Interval
		int						fInternalScanLine;			// Current Scanline
		bool						fRasterIRQ;						// Raster IRQ Flag
		bool						fWindowXYSwitch;				// XY Switch in rasthi
		word						fRasterIRQTarget;				// Raster IRQ Target
		int						fWindowTop;						// Window Top Position
		int						fWindowBottom;					// Window Bottom Position
		int						fWindowLeft;					// Window Left Position
		int						fWindowRight;					// Window Right Position
		int						fWindowWidth;					// Window Width
		int						fWindowHeight;					// Window Height
		byte						fVideoPage;						// Current Video Page
		byte						fSpritePage;					// Current Sprite Page

		byte						fPlaneCount;					// Number of planar bitmaps
		bool						fPlaneSet;						// Bitplane Set (A = false, B = true)
		unsigned int			fPlaneBaseAddr[16];			// Bitplane Address Bases
		unsigned int			fPlaneOffset;					// Offset counter used to build scanline
		byte						fPlaneModulo;					// Bitplane Modulo
		bool						fBGVideoInhibit;				// Inhibit Background Video
		bool						fWideBorder;					// Wide left border?
		bool						fBitmapFloodMode;				// Bitmap Flood Mode? (chunky)
		bool						fFlipPlayfields;				// Flip playfield priorities (tilemap)
		bool						fExpandedChunky;				// Horizontal Expand (chunky mode)
		bool						fDualPFEnabled;				// Dual PF Enabled
		bool						fAltMapBufferSelect[2];		// Playfield map buffer select
		bool						fAltTileSetSelect[2];  		// Playfield tile set select
		bool						fUse8x8Tiles;					// Use 8x8 tiles
		byte						fPFScrollY[2];					// Playfield y-scroll
		byte						fXHWS;							// vreg_xhws
		byte						fLineColour;					// linedraw_colour
		byte						fTargetPalette;				// Target palette (for writes)
		byte						fChunkyWidth;					// Chunky pixel width (1-8)
		bool						fRasterIRQEnable;				// Raster IRQ Enabled
		word						fLineCopStartAddr;			// Line Cop Start Address
		word						fLineCopPC;						// Line Cop Program Counter
		word						fLineCopRegister;				// Line Cop Register Number
		bool						fLineCopRunning;				// Line Cop Running
		word						fLineCopTarget;				// Line Cop Target Scanline

		// Sprites
		SpriteRegister			Sprites[128];					// Actually only 126 or 127
		byte						fSpriteControl;				// vreg_sprctrl
		bool                 fSpriteDoubleBuf;				// Sprites are double-buffered?
		byte						fSpriteBank;					// Double-Buf Sprite Bank
		bool						fSpriteInterleave;			// Interleave Sprites
		bool						fSpritesMatte;					// Matte Mode
		bool						fSpriteForceHigh;				// Force colours high
		bool						fSpriteLowColours;			// Use only colours $00-$7f
		int						fSpritesDirty;

		// Blitter
		byte						fBlitDestMSB;					// blit_dst_msb
		byte 						fBlitSrcMSB;					// blit_src_msb
		byte						fBlitWidth;              	// blit_width
		byte 						fBlitHeight;					// blit_height
		byte						fBlitMisc;						// blit_misc
		short						fBlitSrcModulo;				// blit_src_mod (including MSB from blit_misc)
		short						fBlitDestModulo;				// blit_dst_mod (including MSB from blit_misc)
		word						fBlitSrcLoc;					// blit_src_loc
		word						fBlitDestLoc;					// blit_dst_loc

	protected:
		void __fastcall		RunLineCop(void);
		void __fastcall		BuildBitmapLine(void);
		void __fastcall		BuildTileLine(void);
		void __fastcall		BuildSpriteLine(void);

	public:
		int						fScanLine;						// Current Scanline
		TPalette32				fVideoPalette[2];				// Screen Palettes
		byte						fVideoLine[312][512];		// Palette for current line
		word						fSpriteLine[312][512];		// Sprite palette information
		TPalette32				fDrawPalette[240];			// Palette for drawing
		byte						fLivePalette;					// Live palette (for display)
		bool						fSpritesEnabled;				// Master sprite enable

		// Generic Operations
		bool __fastcall		Tick(unsigned int CycleCount);
		void __fastcall		Reset(void);
		bool __fastcall		GetRasterIRQ(void);
		void __fastcall		ClearIRQ(void);

		// Write Operations
		void __fastcall		WritePalette(word Address, byte Value);
		void __fastcall		WriteRegister(word Address, byte Value);
		void __fastcall		WriteSpriteRegister(word Address, byte Value);
		void __fastcall		WriteDirectVRAM(word Address, byte Value);
		void __fastcall		WriteMappedVRAM(word Address, byte Value);
		void __fastcall		WriteSpriteRAM(word Address, byte Value);
		void __fastcall		WriteBlitter(byte Address, byte Value);

		// Read Operations
		byte __fastcall		ReadMappedVRAM(word Address);
		byte __fastcall		ReadSpriteRAM(word Address);
		byte __fastcall		ReadVREG(void);

		__fastcall 				TOSCAVideo(TOSCABoard *owner);
		__fastcall 				~TOSCAVideo();
};

//---------------------------------------------------------------------------

#endif

