/*	
 *	clipt18.h
 *
 *	P/ECE TMS9918(A) Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2005 Naoyuki Sawa
 *
 *	* Mon Jan 3 13:00:00 JST 2005 Naoyuki Sawa
 *	- 作成開始。
 *	* Sun Jan 30 21:25:00 JST 2005 Naoyuki Sawa
 *	- コメントを間違えてSN76489と書いてしまっていたところをTMS9918に修正。
 *	  プログラム内容の変更はありません。
 */
#ifndef __CLIP_T18_H__
#define __CLIP_T18_H__

/****************************************************************************
 *
 ****************************************************************************/

/* TMS9918_ASMシンボル定義を読み込みます。
 * TMS9918_ASMシンボルの未定義/定義によるC/アセンブラコードの切り替えは、
 * Cソースファイル(*.c)とアセンブラソースファイル(*.s)から参照するので、
 * 別のインクルードファイルに分けています。
 * (C言語特有の定義を含むインクルードファイルをそのままアセンブラソースに
 *  インクルードすると、アセンブルエラーになってしまうため。)
 */
#include "clipt18a.h"

/********** これ以降は書き換えないでください **********/

/* P/ECE以外ではアセンブラコードは使用できません。
 */
#ifndef PIECE
#undef TMS9918_ASM
#endif /*PIECE*/

/****************************************************************************
 *
 ****************************************************************************/

typedef struct _TMS9918 {
	unsigned short addr;		/* + 0,  2: Address (0x0000-0x3fff) ★使用頻度が高いので1命令でアクセスできるよう先頭に配置★ */
	         short latch;		/* + 2,  2: Port#1への書き込み値を保持 (-1:初期状態) */
	unsigned char  reg[8];		/* + 4,  8: Register */
	unsigned char  status;		/* +12,  1: Status */
	unsigned char  resv[3];		/* +13,  3: (予約) */
	unsigned char  vram[0x4000];	/* +16,16K: VRAM (16KB) */
} TMS9918;

/****************************************************************************
 *
 ****************************************************************************/

/* TMS9918_GRAYSCALEシンボルを定義すると、16諧調グレイスケール出力となります。
 * TMS9918_GRAYSCALEシンボルを定義しなければ、16パレットカラー出力となります。
 */
#ifdef PIECE
#define TMS9918_GRAYSCALE
#endif /*PIECE*/

#ifdef TMS9918_GRAYSCALE
/* TMS9918モジュール内部使用です。アプリケーションから使う必要はありません。 */
extern const unsigned char tms9918_grayscale_table[16];
#else /*TMS9918_GRAYSCALE*/
/* 16色カラーのパレットを定義します。Win32のBITMAPINFO.bmiColors[]等の設定に利用してください。 */
extern const unsigned char tms9918_color_table[16][3/*R,G,B*/];
#endif /*TMS9918_GRAYSCALE*/

/****************************************************************************
 *	内部使用
 ****************************************************************************/

void tms9918_update_graphics1(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Graphics I */
void tms9918_update_graphics2(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Graphics II */
void tms9918_update_multicolor(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Multicolor */
void tms9918_update_text(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);		/* Text */

void tms9918_update_sprite00(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Size0, MAG0 */
void tms9918_update_sprite01(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Size0, MAG1 */
void tms9918_update_sprite10(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Size1, MAG0 */
void tms9918_update_sprite11(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);	/* Size1, MAG1 */

/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/

/* TMS9918コアをリセットします。
 * [in]
 *	tms9918		TMS9918構造体。
 * [note]
 *	* アプリケーションプログラムは、少なくとも最初に一度、この関数を呼び出してください。
 *	  その後は、TMS9918リセットを行う場合に、必要に応じて呼び出してください。
 */
void tms9918_reset(TMS9918* tms9918);

/* TMS9918から1バイト読み出します。
 * [in]
 *	tms9918		TMS9918構造体。
 *	mode		  0 : Port#0 (VRAM)
 *			  1 : Port#1 (Status)
 */
int tms9918_read(TMS9918* tms9918, int mode);

/* TMS9918に1バイト書き込みます。
 * [in]
 *	tms9918		TMS9918構造体。
 *	mode		  0 : Port#0 (VRAM)
 *			  1 : Port#1 (Register/Address)
 *	data		書き込むデータ。
 */
void tms9918_write(TMS9918* tms9918, int mode, int data);

/* 画面を描画します。
 * [in]
 *	tms9918		TMS9918構造体。
 *	vbuff		256x192画面バッファ。
 *
 * [note]
 *	* TMS9918_GRAYSCALEが定義されていると、16諧調グレイスケール出力となります。
 *	  TMS9918_GRAYSCALEが定義されていなければ、16パレットカラー出力となります。
 *	* P/ECE用の128x88画面を作成するには、いったん256x192画面を作成したあとで、
 *	  tms9918_reduce()を呼んで画面バッファの内容を縮小してください。
 *	  256x192と128x88画面バッファは共有可能なので、256x192画面バッファだけを用意すれば充分です。
 *	  詳しくは、tms9918_reduce()のコメントを参照してください。
 */
int tms9918_update(TMS9918* tms9918, unsigned char vbuff[/*256 * 192*/]);

#ifdef TMS9918_GRAYSCALE
/* 256x192x16諧調グレイスケールを、128x88x16諧調グレイスケールへ縮小コピーします。
 * [in]
 *	src		256x192x16諧調グレイスケール画面バッファ。
 *	dst		128x 88x16諧調グレイスケール画面バッファ。
 *
 * [note]
 *	* srcとdstは同じアドレスを指していても構いません。
 *	  最終的に128x88の画面イメージだけが必要ならば、256x192と128x88の画面バッファを共通化して、
 *	  メモリを節約できます。
 *		unsigned char vbuff[256*192]; // 前半を[128*88]として使用
 *		tms9918_update(tms9918, vbuff);
 *		tms9918_reduce(vbuff, vbuff);
 *	* この関数は、TMS9918モジュールの他の部分から完全に独立しています。
 *	  256x192x16GS→128x88x16GS縮小を行いたい場面があれば、単独で利用可能です。
 */
void tms9918_reduce(unsigned char dst[/*128*88*/], const unsigned char src[/*256*192*/]);
/* TMS9918モジュール内部使用です。アプリケーションから使う必要はありません。 */
extern const unsigned char tms9918_div6_table[15 * 6 + 1];
#endif TMS9918_GRAYSCALE

#endif /*__CLIP_T18_H__*/
