Virtual Game Console Emulator

[2004.5.22]

ゲーム機のハードウェア・ソフトウェアが抱える問題点:

これらの問題を解決するために、仮想ゲーム機を考えます。
仕様を一般公開し、開発環境も無料で提供します。
ハードウェアにあたるエミュレータ本体は、
多くのプラットフォームに移植することにより、
その寿命を半永久とします。

一度完成されたゲームは、永久にそのままの形で保存されるべきである

という主張を掲げつつ開発中です。(^_^;

目次

トップページへ戻る


仕様 [2004.10.04]
仕様考え中...
(8ビットマシンになっちゃいました)
PROJECT VGCE 8ビットゲーム機仕様  2004.10.04


■メモリマップ

+--------------------------------------------------+ 0000h
|                                                  |
|   Bank #0         ROM/RAM                        |
|                                                  |
+--------------------------------------------------+ 4000h
|                                                  |
|   Bank #1         ROM/RAM                        |
|                                                  |
+--------------------------------------------------+ 8000h
|                                                  |
|   Bank #2         ROM/RAM                        |
|                                                  |
+--------------------------------------------------+ c000h
|                                                  |
|   Bank #3         ROM/RAM                        |
|                                                  |
+--------------------------------------------------+ ffffh

- 4000h を1バンクとして扱う。
- バンクごとに 0-255 のマップ番号でセグメントを指定可能。
  0-127: ROM (<=2MB)  128-255: RAM (64kB)
- バンクごとに ROM/RAM の切り替えが可能。
- メインRAM 64KB (CPUアドレス空間の全領域をRAMにすることが可能)


■I/Oマップ

- 00h 〜 0Fh --- VPU
- 10h 〜 1Fh --- Palette
- 20h 〜 2Fh --- SPU
- 30h 〜 3Fh --- Memory Mapper
- 40h 〜 4Fh --- Timer
- 50h 〜 5Fh --- I/O
- 60h 〜 BFh --- Reserved
- C0h 〜 FFh --- Free


■CPU ---- Z80 21.47727[MHz]

 - 割り込みモード #0 (IM 0) を使用する。 


■VPU ---- 5.369317[MHz]

- BG 256色, SP256色
- Vブランク割り込み              (RST 08h)
- ラスタ割り込み                  (RST 10h)
- スプライトオーバー割り込み      (RST 18h)
- VRAM - VRAM 間 DMA 終了割り込み (RST 20h)


画面解像度は 320×240 固定

- バックグラウンド3枚
- 1タイルは8x8
    
    →1画面分は40×30タイル=1200タイル

- タイルにパレットの下位4ビットを定義する
- タイルインデックスにパレットインデックスの上位4ビットを定義する
    →タイルインデックス12ビット、パレットインデックス4ビット
- パレットは 256 エントリ、 RGB555 で指定する


○許可フラグ/設定値

 コントロールレジスタ#1(00h)に設定できる許可フラグ

下位バイト:

 - Vブランク時に割り込み(RST 08h)発生許可 (D0)
 - ラスタ検出時に割り込み(RST 10h)発生許可 (D1)
 - スプライトオーバー時に割り込み(RST 18h)発生許可 (D2)
 - VRAM - VRAM 間 DMA 終了時に割り込み(RST 20h)発生許可 (D3)
 - 予約 (D4 - D7)

上位バイト:

 - BG1 の表示許可 (D8)
 - BG2 の表示許可 (D9)
 - BG3 の表示許可 (D10)
 - スプライトの表示許可 (D11)
 - 予約 (D12-D15)

  コントロールレジスタ#2(01h)に設定できる値

下位バイト:

 - VRAM アドレスインクリメント (D0-D2)
   000b: 1
   001b: 32
   010b: 64
   011b: 128
   100b: 256
   101b - 111b: 256

 - BGメモリ幅   (D3-D4)
   00b: 32
   01b: 64
   10b: 128
   11b: 256

 - BGメモリ高さ (D5)
   0b: 32
   1b: 64

 - 予約 (D6-D7)


上位バイト:

 - 予約 (D8-D15)


○VRAM

 VRAM #1 = 128kB (BG #1)
 VRAM #2 = 128kB (BG #2)
 VRAM #3 = 128kB (BG #3)
 VRAM #4 = 128kB (SP)
--------------------------
 Total   = 512kB


○SPRAM

SPRAM = 2048 bytes


○パターン定義

VRAM #1 〜 VRAM #3
+----------------------------------------------+
|                                              |
|            PATTERN INDEX TABLE               |
|                                              |
+----------------------------------------------+
|                                              |
|          BACKGROUND PATTERN TABLE            |
|                                              |
+----------------------------------------------+


VRAM #4
+----------------------------------------------+
|                                              |
|             SPRITE PATTERN TABLE             |
|                                              |
+----------------------------------------------+


○ PATTERN INDEX TABLE

後述の BACKGROUND PATTERN TABLE のインデックスを定義する。
このテーブルのサイズは VPU のレジスタから
変更することができる。
32 x 32 〜 256 x 64 まで。

32 x 32 (1024タイル)の設定だと、

+-----------------  ...  -----------------+
|  0|  1|  2|  3|   ...   | 1C| 1D| 1E| 1F|
+-----------------  ...  -----------------+
| 20| 21| 22| 23|   ...   | 3C| 3D| 3E| 3F|
+-----------------  ...  -----------------+
| 40| 41| 42| 43|   ...   | 5C| 5D| 5E| 5F|
+-----------------  ...  -----------------+
        :            :            :
        :            :            :
+-----------------  ...  -----------------+
|3A0|3A1|3A2|3A3|   ...   |3BC|3BD|3BE|3BF|
+-----------------  ...  -----------------+
|3C0|3C1|3C2|3C3|   ...   |3DC|3DD|3DE|3DF|
+-----------------  ...  -----------------+
|3E0|3E1|3E2|3E3|   ...   |3FC|3FD|3FE|3FF|
+-----------------  ...  -----------------+

の番号で指定されたタイルで1画面を構成することになる。



○ BACKGROUND PATTERN TABLE

(1タイルは8x8ピクセルで構成される。)
BG PATTERN TABLE は PATTERN INDEX TABLE の直後からはじまる。
このタイルに表示するパターン(8ビット/ピクセル)のうち、
下位4ビットをこのテーブルに定義する。

1タイルの定義の仕方は以下の通り。

数字 --- VRAMのタイルの先頭番地からのオフセット値 (16進数)
L ------ 下位4ビットの意味 (D0 - D3)
H ------ 上位4ビットの意味 (D4 - D7)

例)

0L  --- VRAM のタイルの先頭番地+ゼロバイトの下位4ビットに
        背景のパターンの下位4ビットを定義する。
1FH --- VRAM のタイルの先頭番地+$1Fバイトの上位4ビットに
        背景のパターンの下位4ビットを定義する。

+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
| 0L | 0H | 1L | 1H | 2L | 2H | 3L | 3H |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
| 4L | 4H | 5L | 5H | 6L | 6H | 7L | 7H |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
| 8L | 8H | 9L | 9H | AL | AH | BL | BH |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
| CL | CH | DL | DH | EL | EH | FL | FH |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
|10L |10H |11L |11H |12L |12H |13L |13H |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
|14L |14H |15L |15H |16L |16H |17L |17H |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
|18L |18H |19L |19H |1AL |1AH |1BL |1BH |
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |
|1CL |1CH |1DL |1DH |1EL |1EH |1FL |1FH |
+----+----+----+----+----+----+----+----+

1タイルのパターン定義に、32 バイト使用する。
1画面は40×30タイル=1200タイルで構成されるから、
1画面分のユニークなパターンを定義するには、1200 x 32 = 38400
バイトの VRAM が必要。


■スプライト(SP)

- 256個
- X、Y幅を独立に 8/16/32/64 に設定可能
- メインRAM上にテーブルを作成→SPRAMに転送
- 回転角度を12ビット(000h - fffh)で指定可能

  スプライトのパターン(パレットインデックスの下位4ビット)は
VRAM #4 に定義する。

  SPのサイズによって、VRAM上のパターンテーブルの
スタート位置を調整する必要がある。
8×8ピクセルのスプライトの場合は、16 ワードで1個分の
パターンを定義するので、16 ワード境界にパターンの先頭を配置する。
2進数で表すと %xxxx xxxx xxxx 0000 のアドレスに配置する
(x は 0 または 1 の値をとる)。

  64×64のスプライトの場合は、8×8タイルで1個分を
構成するから、8 * 8 * 16 = 1024 ワードでパターンを定義する。
この場合は 1024 ワード境界(2進数で表すと %xxxx xx00 0000 0000 のアドレス)
にパターンの先頭を配置する。このとき、上位ビットが6ビット
なので、64k ワードの VRAM 内にユニークに定義できる64×64
スプライトの最大数は 2^6 = 64 個になる。


-----------+-------------------------------+-------------------------
  SP Size  |  Pattern Table Start Address  |  Max Patterns Definable
-----------+-------------------------------+-------------------------
   8x8     |      %xxxx xxxx xxxx 0000     |          4096
   8x16    |      %xxxx xxxx xxx0 0000     |          2048
   16x8    |      %xxxx xxxx xxx0 0000     |          2048
   16x16   |      %xxxx xxxx xx00 0000     |          1024
   32x8    |      %xxxx xxxx xx00 0000     |          1024
   32x16   |      %xxxx xxxx x000 0000     |           512
   32x32   |      %xxxx xxxx 0000 0000     |           256
   64x8    |      %xxxx xxxx x000 0000     |           512
   64x16   |      %xxxx xxxx 0000 0000     |           256
   64x32   |      %xxxx xxx0 0000 0000     |           128
   64x64   |      %xxxx xx00 0000 0000     |            64
-----------+-------------------------------+-------------------------


○SPの設定項目
- パレットの上位4ビット
- パターンインデックス12ビット
- 回転角度12ビット(画面に垂直な軸まわりの回転)
- 背景/SP優先1ビット (P)

○X方向設定項目
- X座標10ビット
- X幅2ビット (XW)

○Y方向設定項目
- Y座標10ビット
- Y幅2ビット (YW)


○SPRAM

スプライトの定義テーブル(1個分)

15                     12      8                             0
 +----------------------+------------------------------------+
 |  PALETTE INDEX D4-D7 |          PATTERN INDEX             |
 +--------------------+-+------------------------------------+
 |                    |P|         ROTATION ANGLE             |
 +--------------------+-+--+---------------------------------+
 |                      |YW|          Y COORDINATE           |
 +----------------------+--+---------------------------------+
 |                      |XW|          X COORDINATE           |
 +----------------------+--+---------------------------------+

- 4ワード/スプライト→1024ワード(2048byte)/256スプライト


■SPU ---- 3.579545[MHz]

- 波形メモリ型PSG4チャネル
- ノイズ2チャネル
- FM音源4チャネル(OPM相当)
- 8-bit ADPCM2チャネル
- ADPCM RAM 64kB (32kB x 2)


○波形メモリ型PSG

- 符号付き 8-bit × 64 波形メモリ


○ADPCM

- リピート再生機能あり
- ストリーミング再生機能なし


■Memory Mapper

 - システムリセット時は Bank #0, Bank #1 が ROM(0000h-7fffh)、
   Bank #2, Bank #3 が RAM (0000h-7fffh)になる。

 - I/O の 30h - 33h に Bank #0 - Bank #3 のマップ番号を書き込む。

 - レジスタは書き込みのみ対応。読み出し値は常に 0ffh。

 - マップ番号 0 - 127 は ROM になり、128 - 255 は RAM になる。
   ただし ROM のサイズが 4000h x 128 よりも小さい場合は、
   ROM の容量が繰り返し現れる。

   例えば最小の 4000h (16kB) のときはどのマップ番号を指定しても
   ROM の 0000h-3fffh のイメージが繰り返し現れる。

   ROM のサイズが 8000h のときは、

   マップ番号 0 に ROM 0000h-3fffh, 
   マップ番号 1 に ROM 4000h-7fffh 
   マップ番号 2 に ROM 0000h-3fffh, 
   マップ番号 3 に ROM 4000h-7fffh 
                 :
                 :

   というように繰り返される。


■I/O

- 未定

目次へ戻る  トップページへ戻る


開発状況 [2004.10.04]

画面表示出ました。 BG3枚による3重スクロール+8×8スプライトのテストです。
まだ8×8スプライトしか実装できてません。
画面にちらばっているちっちゃいのがスプライトです。
動きがバグいです。(←アセンブラへたくそ)


現在、CPUコアに Marat Fayzullin 氏の "Z80 Emulation Package" を 使わせて頂いています。RunZ80 関数を変更していますが、コア部分の変更はありません。

[2004.10.17]

SDCC で上とほぼ同じテストプログラムをCで書き直しました。 ついでに画面を320×240モードにしました(上の ASM 版は256×240)。 ついでにバグもちょこっと修正。 out() 関数が見当たらなかったので、インラインアセンブラを使ってI/Oアクセス関数をテキトウにでっち上げたんですが、 call/ret/レジスタ退避のオーバーヘッドでかなり遅くなってしまいました。 そのためVRAM連続書き込みやSPRAM書き込み処理がやたら遅く、いまのところ実用的でないです。 ・・・というわけで、スプライト処理部分がまだ書き直せていません。(^_^;


まだ SDCC を Z80 のコンパイラとして使うための情報が少なく、 割り込みの公式な(?)実装方法がわからなかったので、 スタートアップコード (crt0.s) から直接Cの関数を名指しでコールするようにしました。

あと、グローバル変数の初期化コード(gsinit)がなぜかRAM領域に配置されてしまい、 実行時に制御がスタートアップコードから未初期化のRAM領域へぶっ飛んでしまいます (gsinit が CODE セグメントではなく DATA セグメントに配置されている感じ?)。 いろいろ試してみたんですが、解決方法がみつかりませんでした。 このあたり、どなたかご存知の方がいましたら教えてください。

とりあえず、グローバル変数の初期化コードをスキップするようにして、上の問題を 回避しました。ですので、現状ではグローバル変数に初期値を指定しても、実行時にその値に初期化されません。

とはいえ、開発にC言語が使えるのはかなりでかいです。 かなり普通にCでプログラムが書けてしまいます。Z80 はいったいどこへ!?っていう感じです。 あとはタイルのパターンとかインデックスとかパレットをブラックボックス化して 使えるツールを用意すれば、なんとかゲームの製作ができそうです。

とりあえず今回作成したプログラム一式をアップロードしておきます。 なお、 SDCC はコンパイル・リンク後に インテルHEX形式で出力するので、コンパイルしたコードをVGCEで実行するには、 インテルHEX→バイナリ変換を行なう必要があります。変換ツールは検索すればいろいろと出てきますが、 私はBHCというプログラムを利用させていただきました(ソースがついていたので)

C言語版画面表示テストプログラム一式

[2004.10.17]追記

SDCC で I/O 入出力を行なうには、sfr文を用いて I/O アドレスを定義すればよいと sdccman に書いてありました。まず sfr at 0x00 VPU_PORT; と定義し、 以後たとえば VPU_PORT = 0xff; と書けばコンパイラは
LD A, #0xff
OUT (VPU_PORT), A

というコードを生成してくれます。これで、I/O 入出力の問題は解決しました。

目次へ戻る  トップページへ戻る


ダウンロード

画面表示テストプログラム一式(vgcetest.asm, vgcetest.rom, vgce.exe)

目次へ戻る  トップページへ戻る


技術関連リンク

以下のページを作成された方々に感謝します。

目次へ戻る  トップページへ戻る


(C) Ki 2004