V9990エミュレーション

9990は幻と言われた9958の後継VDP。

従来のVDPと9990の基本的なVDP設計の違いは、9938/9958から導入された
G4-G7ビットマップグラフィクスモードを引き継ぎ、画面モードや色数、
スプライト表示機能を改善したもの。
NESやファミリーコンピュータの画面モードと同じような画面モードである
9918互換のフォント・タイルビットマップG1,G2モードは9990では削除
されている。
(9918互換のタイル画面、アクセス方法を削除したものだが、
似たような画面モードはP1,P2モードとして9990にもある様子)

9990はVDPコマンドを引き継ぎ、同様の機能を持つ。
画面モードは同時発色数が増え、ビットマップのフィルなどピクセル動作も
9938/9958よりも速い。(およそ23倍高速)

VRAM容量は9938/58は128KByteであるが、9990は512KByteである。
SCR8画面モードであれば8面、SCR5であれば16面まで確保することができる。
また9958のYJKモードをサポートしており、YJK方式のフルカラービットマップを
表示させることができる。

エミュレーション環境ではOpenMSX上のExtension(Carapult上など)でGFX9000を選択する
ことで9990を動作させることができる。
実機ハードウエアに対し、9990を搭載したVDPカードGFX9000を取り付けた状態を
エミュレーションする。(エミュレーション環境ではYJKは未サポートらしい)

OpenMSXのGUI設定ツールであるCatapult設定項目のExtensionは拡張カートリッジのエミュレーションで、
別途ROMイメージが必要な場合もあるが、その際はROMをダウンロードしextensionフォルダの
該当ディレクトリに保存する。GFX9000の場合は特別なROMを必要としない。

OpenMSXでは9990の画面出力はデバックコマンドで切り替える。OpenMSXを起動中、
[F10]を押すとデバックウインドウが表示される。
もしExtensionでGFX9000を選択している場合、内部VDPと拡張VDPを
デバックコマンドで切り替えることができる。
マシン本体の9938/58のVDP画面出力から9990へ切り替える場合は
以下のデバックコマンドを使う。

>set videosource gfx9000
>set videosource msx

これらのコマンドで外付けV9990と、内部V9938/9958が出力する画面を切り替える事が出来る。



9990のI/Oアドレスは0x60-0x6Fに存在する。ソフトウエアを記述する場合は
9990のデータシートに従ってこれらのI/Oポートにアクセスすればよい。
これら9990機能を利用するグラフィック関数や命令はC言語で記述する事が可能だろう。


TurboRエミュレーション環境であればVDPを9990で拡張したMSXBASICとしてPowerBASICが利用できる。
PowerBASICは海外製のソフトウエアだが、BASICインタプリタの言語仕様や特徴そのものは
ROMに搭載されている従来のMSXBASICと全く同一である。PowerBASICはダウンロードが可能。

PowerBASICはVDPとして9990を利用するのでSET PAGE命令がSCR8では8ページ、
SCR5では16ページ確保することができる。
また9990機能を利用するのでCOPY文やLINE文などの描画も格段に高速となっている。


  • 画面機能

9990の画面モードはP1,P2、およびB1-B6モードがある。P1,P2モードは9938/58のTEXT1,TEXT2モードと
同一である。
P1,P2モードはTEXTモード以外に、NESやファミリーコンピュータのような
タイルビットマップとしても使う事が出来るようだ。

B1-B4モードはビットマップグラフィックモード。それぞれ以下の解像度を持つ。

B1,256x212
B2,384x240
B3,512x212
B4,768x240

発色数は32,768色。パレットモードの際は、32,768色中64色を選択可能。
画面モードは解像度を規定するもので、このほかに画素ピクセル当たりの色数を指定し、
画面モードを定める。
モードには以下のような種類があり、約10のモードに分かれる。
色深度はレジスタに値をセットして変更する。解像度と色深度で幾つかの画面モードの
組み合わせが生じる。

16bit/1pixel, フルカラー32,768色、RGBそれぞれ5bit割り当て。
8bit/1pixel , パレットモード32,786色中64色
8bit/1pixel , RGBそれぞれ322ビット割り当て、256色
8bit/1pixel , RGBをYJKデコード、19,268色
8bit/1pixel , YUVデコード、19268色
4bit/1pixel , パレットモード32,768色中16色
2bit/1pixel , パレットモード32,768色中4色

このほかにB5,B6というVGA互換モードのような画面モードを持つ。

B5,640x400
B6,640x480

ビデオメモリはLSIに接続するが、VRAM以外に漢字フォントROMなども接続が可能。

VDPコマンドは従来から追加削除されたものがある。追加された機能は漢字フォント関連の
ビットマップをVRAMに描画する機能。

スプライト機能は16x16のサイズが一画面に125個同時表示可能、一ラインには16個という制限がある。
パターンの定義は9918/38/58と似ているが詳細は不明。


  • IOポート

9990そのものはI/Oポートは0x0-0xFの16ポートがある。
VDPアクセス以外に0x8-0xAに漢字ROMフォントのアクセスの為のポートがある。
9990では漢字ROMフォントはVDPに直接接続する方法をとっている。

I/Oポートを経由したVRAMアクセスは9918互換の9938/58と似ている。
異なるのは9918互換性を取り除いたのでビデオアクセスの際のアドレッシングがシンプルとなり
高速アクセス可能なこと。
ビデオメモリのread/writeはI/OポートP#3を経由してVRAMアドレスレジスタ
へ24bitアドレスをセットし、最後にP#0のI/Oへ
データをr/wするだけ。
(write時はP#4のVDPレジスタ指定を変える)

P#4 ,0
P#3 ,lower address
P#3 ,center address
P#3 ,upper address
P#0 ,data (r/w)


VDPのI/Oポートの意味は以下の通り。GFX9000の場合は0x60-0x6Fで使用する。

P#0 , VRAMアクセス用ポート(r/w)
P#1 , パレットデータ用ポート(r/w)
P#2 , VDPコマンド用データ読み書きポート(r/w)
P#3 , VDPレジスタデータ用ポート(r/w)
P#4 , VDPレジスタ選択用ポート(w)
P#5 , ステータス用(r)
P#6 , 割り込み用(r/w)
P#7 , システム使用(w)
P#8 , JIS第一水準漢字ROMフォントlower address
P#9 , JIS第一水準漢字ROMフォントupper address/データ読み出し用
P#A , JIS第二水準漢字ROMフォント(同)
P#B , JIS第二水準漢字ROMフォント(同)/データ読み出し
P#C-F , 予約

このうちP#4のコマンドはVDPのLMMMなどのビットマップ操作コマンドとは違いVDPレジスタ番号を指定し
アクセスに使用するもの。
LMMMビットマップ操作コマンドはレジスタにセットする。


  • Cコード例

9990(GFX9000)のI/Oアドレスは0x60-0x6Fまでなのでここに出力する。

VDPレジスタへの読み書きはI/Oポートの3,4(0x63,0x64)を使う。

void V9990Reg(unsigned char reg, unsigned char data){
	outp(0x64,reg);
	outp(0x63,data);
}

メモリの読み書きはVRAMアドレスを設定し、データをリードライトする。
VRAMアドレスはVDPレジスタ3つで指定する。データの読み書きはI/OポートP#60を使う。
以下の関数でアドレスを指定後、ポートの0x63をリードライトする。
outp(0x60,data)というようにポートを直接リードライトすることでピクセルデータをセットする。

void V9990Memadr(unsigned long addr,unsigned char rw){
	unsigned char hi,mi,lo

	lo=addr & 0xff;
	mi=(addr >> 8) & 0x3f
	hi=(addr >> 14) & 0x7;

	if (rw) {
		//R#3 VRAM READ ADDRESS REGISTER
		outp(0x64,0x3);
	}else{
		//R#0 VRAM WRITE ADDRESS REGISTER
		outp(0x64,0x0);
	}

	//SET ADDRESS
	outp(0x63,lo);
	outp(0x63,mi);
	outp(0x63,hi);

}

これらの関数を用いて、
以下のコードでVRAMにピクセルを描画することができる。

void main(void){
	V9990Memadr(0,1);
	outp(0x60,255);
}

上の命令は以下のBASICソースと等しい。
外部カートリッジに9990が接続されている状態(port 0x60-0x6f)では、
MSXBASICであれば下記のようなコードでVRAM書き込みを実現できる。

'WRITE REGISTER R#0
out &h64,0

'SET ADDRESS
out &h63,0
out &h63,0
out &h63,0

'WRITE VRAM DATA
out &h60,255

C言語による9990描画例を以下に示す。

extern unsigned char inp(unsigned char);
extern outp(unsigned char,unsigned char);

void V9990Reg(unsigned char reg, unsigned char data);
void V9990Memadr(unsigned long addr, unsigned char rw);

void main(void){
	long i;

	//R#6 SCREEN MODE 256x212 16bit/pixel
	V9990Reg(0x6,0x83);

	//R#7 DISABLE INTERLACE
	V9990Reg(0x7,0x80);

	//R#8 ENABLE SCREEN
	V9990Reg(0x8,0x82);

	//SET VRAM ADDRESS(r=0,w=1)
	V9990Memadr(0x0,1);

	//DRAW
	for(i=0; i<10000; i++){
		outp(0x60,i % 255);
	}

}


  • 画面モードの切り替え

SCRモードの切り替えはVDPレジスタ6,7,8の設定にておこなう。
P1,P2テキストモードとして使用する場合はフォントデータを初期化する必要がある。
パレット(カラーインデクス)モードでは画面モード設定のほかに、適切にパレットを初期化する必要がある。

スクリーンの初期化は以下の数値をR#6にセットするだけで良い。

R#6, 0x83 モード設定
R#7, 0x80 インターレースなし
R#8, 0x82 画面表示許可

以上で画面が表示される。256colr/pixelの場合はこのほかにR#13レジスタをセットする必要がある。
16bit/pixelはR#6だけで動作するらしい。
16bit/pixelモードは、単にR#6を0x83にすればよい。

R#6,0x83 '16bit/pixel
R#13,0x40 '256 mode

パレットモードは以下のように設定する

R#6,0x82 '8bit/pixel
R#13,0x80 'palette mode


	//R#6 SCREEN MODE 256x212 8bit/pixel
	V9990Reg(0x6,0x82);

	//R#13 MODE 256
	V9990Reg(0x13,0x40);

	//R#7 DISABLE INTERLACE
	V9990Reg(0x7,0x80);

	//R#8 ENABLE SCREEN
	V9990Reg(0x8,0x82);


BASICで画面モードを切り替える場合は以下のようにしてスクリーンモードを設定する。

'R#6 SCREEN MODE
out &h64,6
out &h63,&h83

'R#7 NON INTERLACE
out &h64,7
out &h63,&h80

'R#8 ENABLE DISPLAY
out &h64,8
out &h63,&h82

'DRAW PIXEL
for i=0 to 9000
out &h60,i mod 255
next i


  • パレット初期化

パレットモードを利用する場合は、VDPレジスタ設定によって画面モードを切り替える他に、
パレットを設定する必要がある。パレット初期化手順は以下。

	//R#14,0x0
	V9990Reg(0x14,0x0);

	outp(0x61,r)
	outp(0x61,g)
	outp(0x61,b)

BASICで書くと以下のようになる。

'R#14 PALETTE INDEX
out &h64,14
out &h63,0

'SET COLOR CODE(0-31)
for i=0 to 31
out &h61,i
out &h61,i
out &h61,i
next i

パレットモードは8bit/pixelでパレットモードのとき、
32768色中64色パレットが可能。
(1byteサイズのVRAMを使うがパレットインデクスは6bitなので最大64パレット)

4bit/pixelの時、
32768色中16色パレットとなる。

2bit/pixelの時、
32768色中4色パレットとなる。



  • 9990のI/Oポート

P#0, VRAM DATA (R/W)

bit vd7,vd6,vd5,vd4,vd3,vd2,vd1,vd0

P#0(0x60)はVRAMアクセス時の読み書きを行なうポート。
データ書き込みアドレス設定は9990レジスタR#0-3を使う。動作中はウエイト信号が出力される。
データ読み込みアドレスはR#3-5を使う。
VRAMアドレスのオートインクリメント機能も持つ。


P#1, PALETTE (R/W)

pd7,pd6,pd5,pd4,pd3,pd2,pd1,pd0

P#1(0x61)はパレットを変更するためのI/Oポート。
カラーはRGBが32768色の段階を持つので、各色は5bitの長さを持つ。
パレットデータの色情報はRGBそれぞれ5bitなので三回繰り返して設定する。
パレット情報を保持する場所はVRAMにあり、R#14で指定される位置にある。
パレット番号のオートインクリメント機能も持つ。


P#2, COMMAND DATA (R/W)

cd7,cd6,cd5,cd4,cd3,cd2,cd1,cd0

P#2(0x62)はVDPコマンドデータを入出力する。LMMCなどのコマンド時に利用するデータR/Wポート。


P#3, REGISTER DATA (R/W)

rd7,rd6,rd5,rd4,rd3,rd2,rd1,rd0

P#3(0x63)はVDPレジスタに書き込むデータを入出力する。レジスタ番号はP#4(0x64)で指定。
ポートを読み込むとレジスタ内容を得る。


P#4, REGISTER SELECT (W)

WI,RI,ra5,ra4,ra3,ra2,ra1,ra0

レジスタ番号を指定する。9938/58のような方法ではなく9990ではI/Oポートでレジスタ番号を
分けて指定する。
RI/WIはリードライト時のインクリメント指定ビット。このビットが立っているとレジスタ番号は
データの読み書き後に加算される。


P#5, STATUS (R)

TR,VR,HR,BD,0,MCS,EO,CE

9990のステータスを得る。

TR, コマンドデータ転送Redy、P#2アクセスを反映
VR, 縦走査線ブランク識別
HR, 横走査線ブランク識別
BD, SRCHコマンド時の結果
EO, インターレース時のEven/Odd識別
CE, コマンド実行状態
MCS, 主クロック状態


P#6, INTERRUPT FLAG (R/W)

0,0,0,0,0,CE,HI,VI

割り込み状態を示すフラグ。1を書き込むとフラグはリセット。

CE, コマンド実行フラグ
HI, 垂直走査線フラグ
VI, 水平走査線フラグ


P#7, SYSTEM CONTROL (W)

0,0,0,0,0,0,SRS,MCS

内部リセットやマスタークロックの設定。

SRS, システムリセットする。
MCS, 内部・外部クロックを設定



P#8-P#B(0x68-0x6B)までは漢字ROMに関するフォントデータのR/W。9990は漢字フォントROMをI/OポートではなくVDP側に付ける仕組み。P#C-P#F(0x6C-0x6F)は予約


  • 9990のレジスタ(一部)


R#0-2 VRAM WRITE ADDRESS (W)

R#0 a7, a6, a5, a4, a3, a2, a1, a0
R#1 a15,a14,a13,a12,a11,a10, a9, a8
R#2 INC, 0, 0, 0, 0,a18,a17,a16

VDPレジスタの0-2は、VRAM書き込み時のアドレスを指定。書き込み時のアドレス指定専用で、
アドレスは19bitの長さを持つ。
データ書き込み後、INCビット走査でインクリメント時のパルスを作成。



R#3-5 VRAM READ ADDRESS (W)

R#3 a7, a6, a5, a4, a3, a2, a1, a0
R#4 a15,a14,a13,a12,a11,a10, a9, a8
R#5 INC, 0, 0, 0, 0,a18,a17,a16

VDPレジスタの3-5はVRAM読み込み時のアドレス指定。読み込み専用で19bitの長さ。
INCビットでアドレスインクリメント。



R#6-7 SCREEN MODE (R/W)

R#6 dspm1, dspm0, dclkm1, dclkm0, ximm1, ximm0, clrm1, clrm0
R#7 0, c25m, sm1, sm, pal, eo, il, hscn

画面モード設定。

dspm0/1、画面モードを設定、P1/P2/B1-6/及びスタンバイ状態を切り替える
dckm0/1、ドットクロックの設定(分周比の設定)
ximm0/1、全画面の横方向のドット数、256/512/1024/2048から指定
clrm0/1、ピクセル当たりの色数の指定、2/4/8/16bit

c25m、640x480モードの設定(VGA互換?)
sm1、垂直走査線設定(SMと共に使う)
sm、水平走査線周波数の設定。
pal、PAL/NTSC方式の設定
eo、インターレース時のeven/oddの設定
il、インターレース設定
hscn、水平スキャンモードの設定



R#8 CONTROL(R/W)

R#8 disp, spd, yse,vwte, vwm,dmae,vsl1,vsl0

9990の制御。

disp、VRAM内容を画面表示
spd、スプライトの表示・非表示
yse、9990端子のYS信号の出力設定
vwte、9990端子のVRAMシリアルデータバスの制御(デジタイザ用途など)
vwm、シリアルデータバス動作時のVRAM書き込みモード設定
dmae、DMAなどのリクエスト信号端子DREQの設定
VSL0/1、VRAMのタイプ設定



R#9 INTERRUPT (R/W)

R#9 0, 0, 0, 0, 0,iece, ieh, iev
R#10 il7, il6, il5, il4, il3, il2, il1, il0
R#11 iehm, 0, 0, 0, 0, 0, il9, il8
R#12 0, 0, 0, 0, ix3, ix2, ix1, ix0

割り込み設定。

iece、コマンド終了割り込みの設定
iev、垂直帰線期間割り込み
ieh、水平帰線期間割り込み
il0/9、垂直帰線割り込み発生位置の設定
ix0/3、水平帰線期間割り込み位置の設定
iehm、垂直帰線割り込みのラインモードの設定


このほかVDPコマンドやスプライト、パレット設定レジスタなどがある。


  • 余談

9918はTIが設計したビデオプロセッサ。元々は大学生がATARIのゲーム機を真似て作ったものが
最初らしく、当時9918を設計した人は今でもTIで仕事をしているらしいという話が海外の
数年前のカンファレンスで発表された。
9938開発当時もTIの技術者も参加したようだ。

(TIは元々は地質調査の仕事から始まった。半導体の特許を保有しているというだけでなく、米国南部なので恐らくPCやUNIXがない時代の石油探査用の計算処理に関係している。電卓の製造もその名残といえる。Z80で知られるZilogも確か石油など米国南部エネルギー産業資本が入っていた筈である。石油と当時のゲーム機には妙な繋がりがある)

9918の派生品は世の中に幾つかある。
9938は9918にパソコン的なスクリーンモードを追加した改良を施した。
一方でゲーム機に特化して改良されたものはセガの初期のゲーム機である。この設計の流れは
のちのゲームギアやメガドライブに受け継がれた。

9918は任天堂のハードと比較すると仮想スクリーンやハードウエアスクロールが無いという
違いはあるが、タイルビットマップについては基本的に同じである。
MSXと任天堂のファミリーコンピュータを比較すると、VDP(9918)やメインメモリ拡張方式
についてはMSXのほうが簡単でシンプルな設計となっている。
逆に言えば、よりシンプルなMSXを扱えないと当時のファミリーコンピュータのプログラミングはもっと難しいということになる。

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2012年08月19日 20:43
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。