SL9821

はじめに

ダウンロード

使い方

FAQ

実行画面

技術的なはなし

プログラム構成

CPU

テキスト

グラフィック

PEGC

サウンド

PEGCは初期のPC-9821(multi、MATE A)に搭載された1677万色中256色の出力が可能な画面モードです。今更どれほどの価値があるものでもないのですが、せっかくですのでここで分かっている範囲の内容にはなりますが、ずいぶん昔に解析して今回のエミュレータ作成においても参考にしたPEGCの機能をここに書いておこうと思います。(一部の内容は、技術評論社「ざべ no124 1993年9月」の記事「PC-9821の拡張機能解析 [第1回]これが「拡張グラフアーキテクチャ」でござ~る」を参考にしています)

PEGCの概要

まず、グラフィックV-RAMのサイズは512Kバイトで、画面モードとしては400ライン2画面のほか、480ライン1画面のモードを持ちます。
プログラム的な側面としては、描画の方法として1バイト1パレット情報として扱うパックトピクセルモードと8プレーン同時アクセスでEGCのような描画が可能なプレーンモードの2種類があります。
GDCとの関係ですが、これはエミュレータを作って初めて分かったことですが、GDCのPITCHコマンドに対応しています。Windowsのドライバではこの値に128を設定し横幅を1024ドットとして描画処理をしています(縦横の計算がしやすいから?)。その他、SYNCやRESETコマンドは対応していますが、描画系のコマンドやSCROLL、CSRFORMコマンドなどのコマンドの対応状況は不明です。エミュレータとしての実装は非対応です。

使用するポート

256色モードに関連するポートと設定は以下の通りです。

ポート入出力説明
6AhOUT
画面モード切替
21h : 拡張(256色)モード
20h : 標準モード
68h : 2画面モード
69h : 1画面モード
A4hIN/OUT
表示面設定(2画面モードの時のみ有効)
00h : VRAMの前半256KByteを表示面として使用
01h : VRAMの後半256KByteを表示面として使用
A6hOUT
描画面設定(2画面モードの時のみ有効)
00h : プレーンモード時の描画面としてVRAMの前半256KByteを使用
01h : プレーンモード時の描画面としてVRAMの後半256KByteを使用
A8hOUTパレット番号(0~255)
AAhIN/OUT緑の輝度(0~255)
AChIN/OUT赤の輝度(0~255)
AEhIN/OUT青の輝度(0~255)
09A8hIN/OUT
水平走査線切り替え
00h : 24.823KHz(400ライン)
01h : 31.778KHz(480ライン)
※エミュレータ上で定義している理論値です。

使用するアドレス

256色モードでも従来のモードで使用するVRAMと同じアドレス領域を使用しますが、使い方がかなり異なります。

アドレス説明
A8000h~AFFFFh パックトピクセルモード時にバンク切り替えでVRAMをウインドウ表示させる領域1、バンクの切り替えは後述のE0004hで設定
プレーンモード時にVRAMへアクセスする領域
B0000h~B7FFFh パックトピクセルモード時にバンク切り替えでVRAMをウインドウ表示させる領域2、バンクの切り替えは後述のE0006hで設定
プレーンモード時にVRAMへアクセスする領域、1画面モードのときにのみVRAM全体のうちの後半の領域として使用可能
B8000h~BFFFFh 未使用
E0000h~E7FFFhメモリマップトIO

メモリマップトIO

メモリマップトIOはパックトピクセルモード時のバンク切り替えのページ切り替えと、プレーンモードにおける機能設定のための領域になります。未使用のビットがクリアされることはありますが、基本的に有効なアドレスに対してのリードライトは可能です。
表中の、"-"は書き込んだ後読み込んでも値が反映されていないビット(おそらく機能なし)、"○"は機能がある程度分かっているビット、"?"は書き込んだ値が反映されるものの機能が不明なビットです。"△"は32ビットでVRAMへアクセスするときにのみ有効になるビットです。
また以降、表中のラスタオペレーション等の説明でよく使われる言葉として、
ソースデータとは、CPUからVRAMへ書き込むデータで、設定により直前に読み出したVRAMデータとCPUのデータのいずれかを選択します。シフトバッファを経由するのでシフト設定の影響を受けます。
ディスティネーションデータとは、書き込むアドレスの演算前のVRAMデータのことです。
パターンレジスタは、PEGCの内部データとして持っているデータで、設定によりVRAM読み出し時に更新されます。また、PEGCの場合E0120h以降を参照することでパターンレジスタの内容が確認できます。

アドレスビット説明
1514131211109876543210
E0004h------------
領域A8000h~AFFFFhのバンク指定
512KバイトのVRAM領域を32Kバイト単位に区切った先頭からのインデックス番号を指定、パックトピクセルモードで使用
E0006h------------
領域B0000h~B7FFFhのバンク指定
512KバイトのVRAM領域を32Kバイト単位に区切った先頭からのインデックス番号を指定、パックトピクセルモードで使用
E0100h---------------
モード切替
0 : パックトピクセルモード
1 : プレーンモードモード
E0102h--------------?
アッパーメモリ領域のVRAM切り替え
0 : アドレス00F00000h~00F80000h、FFF00000h~FFF80000hをVRAMとして使用しない
1 : アドレス00F00000h~00F80000h、FFF00000h~FFF80000hをVRAMとして使用する
E0104h--------
アクセスプレーン(EGCにおけるポート04A0hに相当)
bit 7~0
0 : プレーンへのアクセスは有効
1 : プレーンへのアクセスは無効
E0108h?
ラスタオペレーション設定(EGCにおけるポート04A4hに近い機能)
bit 15 アドレスE0120h以降の領域で読み出し可能なパターンレジスタのデータ構成を指定
0 : プレーン毎に分割した2バイト(4バイト)データ×8プレーン
1 : ピクセル毎に分割した1バイトのデータ×16ピクセル(32ピクセル)
(括弧内はパターンレジスタが更新されるアクセスを32ビットで行った場合)
bit 13 パターンレジスタの更新
0 : VRAMへアクセスしたときにパターンレジスタを更新しない
1 : VRAMへアクセスしたときにアクセスしたVRAMデータでパターンレジスタを更新する(bit 8が0である必要があります)
bit 12 表示方式の設定
0 : VRAMへのライトに対しソースデータの値に応じて以下の条件で更新する
ソースデータのビットが、
0に対してはアクセスプレーン(E0104h)とディスティネーションデータの論理積(and)
1に対してはアクセスプレーンのnot値とディスティネーションデータの論理和(or)
1 : VRAMへのライトはこのレジスタのビット11~0で決定される描画方法を用いる(以下のビットの説明はbit 12が1のとき)
bit 11、10 論理演算の方法を指定
00 : ソースデータとディスティネーションデータとパターンレジスタを使用してラスタオペレーションを行う
ラスタオペレーションの構成はこのレジスタのbit7~0で指定し、各ビットの意味は以下の通り(EGCと同じ)
bit 7 : S and D and P
bit 6 : S and D and ~P
bit 5 : S and ~D and P
bit 4 : S and ~D and ~P
bit 3 : ~S and D and P
bit 2 : ~S and D and ~P
bit 1 : ~S and ~D and P
bit 0 : ~S and ~D and ~P
※ここで、Sはソースデータ、Dはディスティネーションデータ、Pはパターンレジスタを表し、~はnot値のこと
01 : ソースデータとディスティネーションデータとE0118hで指定されるパレットデータを使用して、ラスタオペレーションを行う
bit 7 : S and D and C8
bit 6 : S and D and ~C8
bit 5 : S and ~D and C8
bit 4 : S and ~D and ~C8
bit 3 : ~S and D and C8
bit 2 : ~S and D and ~C8
bit 1 : ~S and ~D and C8
bit 0 : ~S and ~D and ~C8
※ここで、Sはソースデータ、Dはディスティネーションデータ、C8はE0118hの値を表し、~はnot値のこと
10 : ソースデータとディスティネーションデータとE0114hで指定されるパレットデータを使用して、ラスタオペレーションを行う
参照するカラーパレットが異なるほかは、設定値01と同じ
11 : ソースデータとディスティネーションデータとE0114h、E0118hで指定されるパレットデータを使用して、ラスタオペレーションを行う(EGCには対応する機能がない設定)
bit 7 : S and D and C4
bit 6 : S and D and ~C4
bit 5 : S and ~D and C4
bit 4 : S and ~D and ~C4
bit 3 : ~S and D and C8
bit 2 : ~S and D and ~C8
bit 1 : ~S and ~D and C8
bit 0 : ~S and ~D and ~C8
※ここで、Sはソースデータ、Dはディスティネーションデータ、C4はE0114hの値、C8はE0118hの値を表し、~はnot値のこと
bit 9 シフタの方向設定(EGCのポート04AChのビット12に相当)
0 : 右方向(インクリメンタル)シフト
1 : 左方向(デクリメンタル)シフト
bit 8 ソースデータの内容
0 : 直前に読み出したVRAMデータ
1 : CPUのデータ
bit 7~0 ラスタオペレーションの指定、セットしたビットの演算の論理和が最終的な演算結果になる。詳細は上記bit11、10を参照
E010Ah---------------
VRAMをリードしたときに読み出されるデータの選択
bit 0
0 : 不定値(意味のない値)が読める
1 : 読み出したVRAMのビットがE0114hで指定したカラーパレットと同じ場合は1、異なるときは0になるような値を返す。このときの比較はE0104hのアクセスプレーンの影響を受けるためアクセスプレーンで許可されたプレーンのみチェックされる。またこの機能を有効にするためにはE0108hのビット8が0である必要がある
E010Ch
マスクレジスタ(EGCにおけるポート04A8hに相当)
bit 15~0(32ビットアクセス時はE010ChからE010Fhまでのbit 31~0)
0 : マスクする(書き込みは無視される)
1 : マスクしない
E0110h----
ブロック転送ビット長、転送サイズ-1を設定。最大値は4095(EGCにおけるポート04AEhに相当)
E0112h------
シフタへの読み込み時および書き込み時のシフト数を設定する(EGCにおける04AChのbit7~4、bit3~0に相当)
なお、表中の上位8ビットへはE0113hへの8ビットアクセスでもリードライト可能(表の都合上ひとまとめで説明しています)
bit 11(12)~8
ライト時のビットシフト数を指定、最大5ビットまで有効でVRAMへ32ビットでライトした場合に5ビット目が有効になる
bit 3(4)~0
リード時のビットシフト数を指定、最大5ビットまで有効でVRAMへ32ビットでリードした場合に5ビット目が有効になる
E0114h--------
カラーパレット1(EGCにおけるポート04A6h、フォアグラウンドカラーに相当)
bit 7~0
カラーパレット番号
E0118h--------
カラーパレット2(EGCにおけるポート04AAh、バックグラウンドカラーに相当)
bit 7~0
カラーパレット番号
E0120h~
パターンレジスタの内容
この領域はE0108hのbit 15の値により2種類の読み方が出来る
また、パターンレジスタは更新時のメモリアクセスのサイズにより16ビットと32ビットのいずれかのサイズをとる
データは常に4バイトアライメントで配置され、並びかたは以下の通り
・E0108h bit 15 が0のとき、16(32)ドット×8プレーン構成
E0120h bit 15(31) ~ 0 プレーン0のビットパターン(以下同様)
E0124h bit 15(31) ~ 0 プレーン1
E0128h bit 15(31) ~ 0 プレーン2
E012Ch bit 15(31) ~ 0 プレーン3
E0130h bit 15(31) ~ 0 プレーン4
E0134h bit 15(31) ~ 0 プレーン5
E0138h bit 15(31) ~ 0 プレーン6
E013Ch bit 15(31) ~ 0 プレーン7
・E0108h bit 15 が1のとき、1パレットデータ×16(32)ピクセル
E0120h bit 7 ~ 0 (左から数えて)ピクセル 0のパレット番号(以下同様)
E0124h bit 7 ~ 0 ピクセル 1
E0128h bit 7 ~ 0 ピクセル 2
E012Ch bit 7 ~ 0 ピクセル 3
E0130h bit 7 ~ 0 ピクセル 4
E0134h bit 7 ~ 0 ピクセル 5
E0138h bit 7 ~ 0 ピクセル 6
E013Ch bit 7 ~ 0 ピクセル 7
E0140h bit 7 ~ 0 ピクセル 8
E0144h bit 7 ~ 0 ピクセル 9
E0148h bit 7 ~ 0 ピクセル 10
E014Ch bit 7 ~ 0 ピクセル 11
E0150h bit 7 ~ 0 ピクセル 12
E0154h bit 7 ~ 0 ピクセル 13
E0158h bit 7 ~ 0 ピクセル 14
E015Ch bit 7 ~ 0 ピクセル 15
※以降はパターンレジスタが32ビットのとき
E0160h bit 7 ~ 0 ピクセル 16
E0164h bit 7 ~ 0 ピクセル 17
E0168h bit 7 ~ 0 ピクセル 18
E016Ch bit 7 ~ 0 ピクセル 19
E0170h bit 7 ~ 0 ピクセル 20
E0174h bit 7 ~ 0 ピクセル 21
E0178h bit 7 ~ 0 ピクセル 22
E017Ch bit 7 ~ 0 ピクセル 23
E0180h bit 7 ~ 0 ピクセル 24
E0184h bit 7 ~ 0 ピクセル 25
E0188h bit 7 ~ 0 ピクセル 26
E018Ch bit 7 ~ 0 ピクセル 27
E0190h bit 7 ~ 0 ピクセル 28
E0194h bit 7 ~ 0 ピクセル 29
E0198h bit 7 ~ 0 ピクセル 30
E019Ch bit 7 ~ 0 ピクセル 31

プレーンモードの設定例

最後に簡単な設定例を例示します。
PEGCのプレーンモードはほぼEGCに対応する機能があるため、EGCと同じように設定することで動作させることが可能です。
前のページでEGCを使って画面全体を2ドット左へシフトするときの設定を例として出しましたが、それと同じことをPEGCのプレーンモードで行うときのことを考えてみます。
まず、EGCのケースを再度確認すると以下のようになっています。

・ポート04A0hにFFF0hを設定、すべてのプレーンへのアクセスを許可
・ポート04A2hに00FFhを設定、フォアグラウンドカラーとバックグラウンドカラーは無効
・ポート04A6hに28F0hを設定、ROPモード、ソースデータはリードしたVRAMデータ、ROPパターンはソースデータのみ
・ポート04A8hにFFFFhを設定、全ビット使用許可(マスクビットなし)
・ポート04AChに0002hを設定、転送方向インクリメンタル、ソースシフト2ビット、ディスティネーションシフト0ビット
・ポート04AEhに637を設定、転送サイズを638ビット
これに対し、機能的な対応関係を元にPEGCのプレーンモードの場合を考えると、
・E0100hに0001hを設定、描画モードにプレーンモードを指定
・E0104hにFF00hを設定、すべてのプレーンへのアクセスを許可
・E0108hに10F0hを設定、ROPモードを指定、転送方向インクリメンタル、ソースデータはリードしたVRAMデータ、ROPパターンはソースデータのみ
・E010ChにFFFFhを設定、全ビット使用許可(マスクビットなし)
・E0110hに637を設定、転送サイズを638ビット
・E0112hに0002hを設定、ソースシフト2ビット、ディスティネーションシフト0ビット
以上のような設定になります。なお、ROPの結果ライトされるのはソースデータのみなので、E0108hのbit11、10に関しては値を変えても結果は変わりません。
VRAMへのアクセスの注意点はEGCと同じで、最初の手順としてオフセット0のリード、オフセット2のリード、オフセット0へのライト、以降オフセットをずらしながらリードとライトを繰り返すという手順は同じです。違う点としては、PEGCは32ビットアクセスが可能なので32ビットでアクセスすればより高速に処理が実行できます。
余談ですが、画面を左へシフトする処理としては、転送方向をデクリメンタル、ソースシフトを0ビット、ディスティネーションシフトを2ビットに設定し、画面の右側からアドレスをデクリメントしながら転送処理をするという方法でも実現可能です。この場合はリードとライトは初めから交互に同じオフセットに対して行います。インクリメンタルな方向での実現方法を例に取り上げたのは、シフトバッファがアンダーフロー状態になりうることとその対処方法についての説明のためです。