Documentation

This commit is contained in:
Jonathan Campbell
2020-05-03 02:10:54 -07:00
parent b5815d4520
commit 057ae46067
6 changed files with 17328 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,390 @@
<html style><!--
Page saved with SingleFile
url: http://nickle.shimbe.net/pegc.html
saved date: Sun May 03 2020 02:06:51 GMT-0700 (Pacific Daylight Time)
--><meta charset=utf-8>
<meta name=GENERATOR content="HOTALL Ver.7.0iW">
<title>PC-9821 PEGC</title>
<link type=image/x-icon rel="shortcut icon" href="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="><link rel=canonical href=http://nickle.shimbe.net/pegc.html></head>
<body>
<p>
<div align=CENTER><font size=6><b>PC-9821 グラフィック機能(PEGC)</b></font><br></div>
<div align=LEFT><hr><br>
<font size=4><b>メモリマップ</b></font><br>
<br>
まず最初に色モード時のグラフィック制御に関連するメモリマップを簡単に書いておきます。VRAMの位置は色モードの位置を使用するのですが、VRAMサイズが大きいためメインメモリに展開しきれないためにVRAMの一部だけを見せるようなウインドウ方式をとっています。<br>
<br>
<table border>
<tbody><tr>
<td>
<div align=CENTER>:<br>
FFFFFH<br>
:<br>
:</div><td colspan=2><br></td>
</tr>
<tr>
<td>
<div align=CENTER>E7FFFH<br>
:<br>
E0000H</div><td colspan=2>
PEGC<br>
メモリマップトI/O</td>
</tr>
<tr>
<td>
<div align=CENTER>:<br>
:</div><td colspan=2><br></td>
</tr>
<tr>
<td>
<div align=CENTER>B7FFFH<br>
:<br>
B0000H</div><td>
パックトピクセルモード<br>
VRAMウインドウ<td rowspan=2>
プレーンモード<br>
プレーンアクセス領域</td>
</tr>
<tr>
<td>
<div align=CENTER>AF000H<br>
:<br>
A8000H</div><td>VRAMウインドウ</td>
</tr>
<tr>
<td>
<div align=CENTER>:<br>
:<br>
H</div><td colspan=2><br></td>
</tr>
</table><br>
<hr><br>
<font size=4><b>メモリマップトI/O</b></font><br>
以前書いた資料をもとに書いているのですが書きながら意味不明なところがあったりします。現状はそのままにしていますが確認次第補足したいと思います。<br>
EGCを知っている場合EGCと対比しながらのほうがわかりやすいと思います。説明が下手なもので...()ゞ<br>
それと、あくまで設定をいろいろ変えて現象から推定した機能であるため間違いがあるかもしれませんが、あらかじめご了承ください。<br>
参考までに調べていたのは初代の無印9821です。この機種ではVRAMへの32ビットアクセスが可能でしたが、後継の機種では16ビットアクセスしか許されていないという話も聞くので、パターンデータ関連でダブルワードのことを書いてありますが、この辺は対応していない機種もあるかもしれません。<br>
無印9821では一応動作確認しています。<br>
<br>
<b>記号の意味</b><br>
○...機能あり<br>
×...機能なし<br>
...機能なしもしくは不明(ライトデータのリードは可能だがが機能がわからない)<br>
<br>
<br>
<table border>
<tbody><tr>
<td rowspan=2><div align=CENTER>メモリ</div><td colspan=16><div align=CENTER>ビット</div><td rowspan=2><div align=LEFT>説明</div></td>
</tr>
<tr>
<td><div align=CENTER><font size=2>15</font></div><td><font size=2>14</font><td><font size=2>13</font><td><font size=2>12</font><td><font size=2>11</font><td><font size=2>10</font><td><font size=2>9</font><td><font size=2>8</font><td><font size=2>7</font><td><font size=2>6</font><td><font size=2>5</font><td><font size=2>4</font><td><font size=2>3</font><td><font size=2>2</font><td><font size=2>1</font><td><font size=2>0</font></td>
</tr>
<tr>
<td><div align=CENTER>E0004H</div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<div align=LEFT><font size=2>パックトピクセルモード時A8000HAFFFFHに呼び出すVRAMバンク領域</font><br>
<font size=2>(実際に取りうる範囲はHFH)</font></div></td>
</tr>
<tr>
<td><div align=CENTER>E0006H</div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<div align=LEFT><font size=2>パックトピクセルモード時B0000HB7FFFHに呼び出すVRAMバンク領域</font><br>
<font size=2>(実際に取りうる範囲はHFH)</font></div></td>
</tr>
<tr>
<td>E0100H<td colspan=8><br><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>0 : パックトピクセルモード</font><br>
<font size=2> : プレーンモード</font></td>
</tr>
<tr>
<td>E0102H<td colspan=8><br><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><font size=2>未確認</font></td>
</tr>
<tr>
<td>E0104H<td colspan=8><br><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>プレーンごとのアクセスプレーン(AP)の有効/無効設定(論理演算処理を行うプレーンの指定)</font><br>
<font size=2>0 : 有効</font><br>
<font size=2>1 : 無効</font></td>
</tr>
<tr>
<td rowspan=8><div align=CENTER>E0108H</div><td><font size=2></font><td colspan=15><br><td>
<font size=2>ラスタオペレーション(ROP)時に使用するE0120H以降のパターンデータの形態を指定する</font><br>
<font size=2>0 : プレーンごとに分割した2(4)バイトデータ×8プレーン</font><br>
<font size=2>1 : ドットごとに分割した1バイトデータ×16(32)ドット</font><br>
<font size=2>※よく覚えてませんが括弧のなかと外の違いはアドレスへのアクセスによって違ったような...ワードアクセスとダブルワードアクセスってことで、バイトアクセスは無効だったのかな?</font></td>
</tr>
<tr>
<td><br><td><div align=CENTER><font size=2></font></div><td colspan=14><br><td><div align=LEFT><font size=2>不明</font></div></td>
</tr>
<tr>
<td colspan=2><br><td><div align=CENTER><font size=2></font></div><td colspan=13><br><td>
<div align=LEFT><font size=2>1 : VRAMを読み込んだ位置のデータをパターンデータの領域(E0120H)にビット15で指定した形式で展開する。ビット8が0である必要がある</font><br>
<font size=2>0 : 上記機能の無効</font></div></td>
</tr>
<tr>
<td colspan=3><br><td><div align=CENTER><font size=2></font></div><td colspan=12><br><td>
<div align=LEFT><font size=2>VRAMへのライト時の表示方式の設定</font><br>
<font size=2>0 : CPUデータのビットが</font><br>
<font size=2> 0のとき AP and D</font><br>
<font size=2> 1のとき (not AP) or D</font><br>
<font size=2>※ AP ... アクセスプレーン(E0104H)</font><br>
<font size=2>D ... ディスティネーションデータ(VRAM上のデータ)</font><br>
<br>
<font size=2>1: ビット110を用いて表示方式を設定する。</font><br>
<font size=2>ビット110の説明はビット12が1のときのもので、0のときは無効</font></div></td>
</tr>
<tr>
<td colspan=4><br><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td colspan=10><br><td>
<div align=LEFT><font size=2>ラスタオペレーション(ROP)の方法を指定する。</font><br>
<font size=2>ROPにはビット70を使用し、表示結果には各ROPデータの論理和が出力される。</font><br>
<font size=2>00 : CPUデータ、ディスティネーションデータ、パターンデータを使用する。</font><br>
<font size=2>01 : CPUデータ、ディスティネーションデータ、カラーコード2(E0118H)を使用する。</font><br>
<font size=2>10 : CPUデータ、ディスティネーションデータ、カラーコード1(E0114H)を使用する。</font><br>
<font size=2>11 : CPUデータ、ディスティネーションデータ、カラーコード1および2を使用する。</font></div></td>
</tr>
<tr>
<td colspan=6><br><td><div align=CENTER><font size=2></font></div><td colspan=9><br><td>
<div align=LEFT><font size=2>E0112H,E0113Hのビットシフトの方向を決定する</font><br>
<font size=2>0 : 右方向へのシフト</font><br>
<font size=2>1 : 左方向へのシフト</font></div></td>
</tr>
<tr>
<td colspan=7><br><td><div align=CENTER><font size=2></font></div><td colspan=8><br><td>
<div align=LEFT><font size=2>CPUデータの内容</font><br>
<font size=2>0 : 直前に読み込んだVRAMデータ</font><br>
<font size=2>1 : レジスタの内容</font></div></td>
</tr>
<tr>
<td colspan=8><br><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<div align=LEFT><font size=2>ROPデータ。ビット11,10で指定されたデータを使用してROPを行う。</font><br>
<table height=0 cellspacing=0>
<tbody><tr>
<td><font size=2>bit7:</font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>P</font></td>
</tr>
<tr>
<td><font size=2>bit6: </font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>(not P)</font></td>
</tr>
<tr>
<td><font size=2>bit5: </font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>P</font></td>
</tr>
<tr>
<td><font size=2>bit4: </font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>(not P)</font></td>
</tr>
<tr>
<td><font size=2>bit3: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>P</font></td>
</tr>
<tr>
<td><font size=2>bit2: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>(not P)</font></td>
</tr>
<tr>
<td><font size=2>bit1: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>P</font></td>
</tr>
<tr>
<td><font size=2>bit0: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>(not P)</font></td>
</tr>
</table><br>
<font size=2>S...CPUデータ</font><br>
<font size=2>D...ディスティネーションデータ(書きこみ先のVRAMデータ)</font><br>
<font size=2>P...ビット11,10が00のときパターンデータ、01のときカラーコード2、10のときカラーコード1</font><br>
<br>
<font size=2>ただしビット11,10が11のときは下記のようになる。</font><br>
<table height=0 cellspacing=0>
<tbody><tr>
<td><font size=2>bit7:</font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>C1</font></td>
</tr>
<tr>
<td><font size=2>bit6: </font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>(not C1)</font></td>
</tr>
<tr>
<td><font size=2>bit5: </font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>C1</font></td>
</tr>
<tr>
<td><font size=2>bit4: </font><td><font size=2>S</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>(not C1)</font></td>
</tr>
<tr>
<td><font size=2>bit3: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>C2</font></td>
</tr>
<tr>
<td><font size=2>bit2: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>D</font><td><font size=2> and </font><td><font size=2>(not C2)</font></td>
</tr>
<tr>
<td><font size=2>bit1: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>C2</font></td>
</tr>
<tr>
<td><font size=2>bit0: </font><td><font size=2>(not S)</font><td><font size=2> and </font><td><font size=2>(not D)</font><td><font size=2> and </font><td><font size=2>(not C2)</font></td>
</tr>
</table><br>
<font size=2>C1...カラーコード1</font><br>
<font size=2>C2...カラーコード2</font></div></td>
</tr>
<tr>
<td>E010AH<td colspan=8><br><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>1 : A8000H以降のVRAM領域にE0114Hで指定したパレットナンバーとディスティネーションデータのプレーンごとの論理積を書き出す。その際E0104Hのアクセスプレーンの制約を受ける。</font><br>
<font size=2>E0108Hのビットが0である必要がある。</font><br>
<font size=2>AP and D and C1</font></td>
</tr>
<tr>
<td>E010CH<td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td rowspan=2>
<font size=2>マスクレジスタ</font><br>
<font size=2>ビット150または310の範囲で指定</font><br>
<font size=2>0 : マスクする</font><br>
<font size=2>1 : マスクしない</font></td>
</tr>
<tr>
<td>E010EH<td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font></td>
</tr>
<tr>
<td>E0110H<td><font size=2>×</font><td><font size=2>×</font><td><font size=2>×</font><td><font size=2>×</font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td><font size=2></font><td>
<font size=2>ブロック転送ビット長</font><br>
<font size=2>(04095) + 1ビット(ドット)</font><br>
<font size=2>(特別なことをしない限り639を設定するのが無難)</font></td>
</tr>
<tr>
<td>E0112H<td colspan=8><br><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>読み出し時のビットシフト長。ビット4は32ビットアクセスのみ有効</font><br>
<font size=2>VRAMデータを読み込む際、右(左)シフトしたところから読み出す。ただし、E0112Hの値がE0113Hより大きいときは一番最初の読み出しだけではデータが不足するため(シフトして空いた下位(上位)のビットは次の読み込みの際にシフトによってあふれたデータが入るようになっている)そのまま書き込んでも表示が無視されるため、書き込む前にもう一度読み込みを行う必要がある</font></td>
</tr>
<tr>
<td>E0113H<td colspan=8><br><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2>×</font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>書きこみ時のビットシフト長。ビット4は32ビットアクセスのみ有効</font><br>
<font size=2>VRAMデータを書き込む際、右(左)にシフトして書き込む。シフトによって空いたスペースには直前に書き込んだデータの、シフトによってあふれた部分が書かれる。</font></td>
</tr>
<tr>
<td>E0114H<td colspan=8><br><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>カラーコード1</font><br>
<font size=2>ROPで使用する</font></td>
</tr>
<tr>
<td>E0118H<td colspan=8><br><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td>
<font size=2>カラーコード2</font><br>
<font size=2>ROPで使用する</font></td>
</tr>
<tr>
<td>E0120H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td rowspan=16>
<font size=2>ROPのパターンデータ</font><br>
<font size=2>上位16ビット(△)はダブルワードアクセス時のみ有効</font><br>
</td>
</tr>
<tr>
<td>E0122H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0124H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0126H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0128H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E012AH<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E012CH<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E012EH<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0130H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0132H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0134H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0136H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E0138H<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E013AH<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E013CH<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
<tr>
<td>E013EH<td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div><td><div align=CENTER><font size=2></font></div></td>
</tr>
</table><br>
<hr><br>
<font size=4><b>I/Oポート</b></font><br>
<br>
256制御に関連するI/Oポートも紹介しておきます。ほかにもあったような気がするのですが、手元に資料が残ってないのでわかるものだけです。<br>
(確かテキストとグラフィックを合成するときにテキストをずらして表示させるポートがあったと思うのですが...)<br>
<br>
<table border>
<tbody><tr>
<td>ポート<td>説明</td>
</tr>
<tr>
<td>6AH<td>
<font size=2>ライトモードレジスタ(それ以外の機能については省略)</font><br>
<font size=2>68H : 2画面モード</font><br>
<font size=2>69H : 1画面モード</font></td>
</tr>
<tr>
<td>A4H<td>
<font size=2>表示画面選択(0,1)</font><br>
<font size=2>2画面モード時のみ有効</font></td>
</tr>
<tr>
<td>A6H<td>
<font size=2>描画画面選択(0,1)</font><br>
<font size=2>2画面モード時のみ有効</font></td>
</tr>
<tr>
<td>A8H<td><font size=2>パレット番号(00HFFH)</font></td>
</tr>
<tr>
<td>AAH<td><font size=2>緑成分(00HFFH)</font></td>
</tr>
<tr>
<td>ACH<td><font size=2>赤成分(00HFFH)</font></td>
</tr>
<tr>
<td>AEH<td><font size=2>青成分(00HFFH)</font></td>
</tr>
</table><br>
<hr><br>
<font size=4><b>パックトピクセルモード時の表示範囲とVRAMバンク領域の関係</b></font><br>
パックトピクセルモード時のVRAMアクセスはVRAM領域を32kバイトごとに区切り、その単位でウインドウ領域に表示して行います。<br>
そこでバンク範囲とドットの関係をわかりやすく表にしておきます。<br>
<br>
<table border>
<tbody><tr>
<td>バンク<td>範囲</td>
</tr>
<tr>
<td>0<td>(0,0)-(127,51)</td>
</tr>
<tr>
<td>1<td>(128,51)-(255,102)</td>
</tr>
<tr>
<td>2<td>(256,102)-(383,153)</td>
</tr>
<tr>
<td>3<td>(384,153)-(511,204)</td>
</tr>
<tr>
<td>4<td>(512,204)-(639,255)</td>
</tr>
<tr>
<td>5<td>(0,256)-(127,307)</td>
</tr>
<tr>
<td>6<td>(127,307)-(255,358)</td>
</tr>
<tr>
<td>7<td>(256,358)-(383,409)</td>
</tr>
<tr>
<td>8<td>(384,409)-(511,460)</td>
</tr>
<tr>
<td>9<td>(512,460)-(639,511)</td>
</tr>
</table><br></div>
<br><p></p>

View File

@@ -0,0 +1,354 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html style lang=ja-JP><!--
Page saved with SingleFile
url: http://www.satotomi.com/sl9821/sl9821_tec5.html
saved date: Sun May 03 2020 02:10:21 GMT-0700 (Pacific Daylight Time)
--><meta charset=utf-8>
<meta http-equiv=content-language content=ja>
<meta http-equiv=Content-Style-Type content=text/css>
<meta name=viewport content="width=device-width, maximum-scale=1, initial-scale=1, user-scalable=no">
<style>:root{--sf-img-1:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHoAAAABCAYAAAARvLrmAAAATklEQVQY02NQUlL6D8KKior/QBgbHwf7HyE1QPwf2Ux8GF0/mjko4qSYgW4OLjuQ1eIx6x8U/yfGDmxqYOGGJ8z+ofsJl1+xuR8Jo5gHAAdSqT9I37gmAAAAAElFTkSuQmCC")}body{background:#eee var(--sf-img-1) left repeat-y;margin:0;font:10pt/1.6 "ヒラギノ角ゴ Pro W3","メイリオ","Hiragino Kaku Gothic Pro","Meiryo",sans-serif}a{text-decoration:none}p{border:solid 0px;margin:0px;line-height:1.6}p.title{font-size:18pt;color:#fff;background:#222;border:solid 2px #222;padding-left:8px}td.empty{color:#fff;background:#222}td.chapter a{display:block;height:100%;width:100%}td.chapter a:link{color:#fff}td.chapter a:visited{color:#fff}td.chapter a:active{color:#fff}td.chapter a:hover{color:#fff;background-color:#888}td.chapter td.select{color:#000;background-color:#eee}td.chapter p.s2{border-left:solid 8px #222}td.chapter p{font-size:11pt}td.chapter{color:#fff;background-color:#222}td.content a:hover{text-decoration:underline}td.content h3{font-size:14pt;text-align:center}td.content h4{font-size:12pt;padding:6px 8px 2px;border-left:solid 6px #000;border-bottom:solid 1px #000;background:#ccc}td.content{font-size:11pt;text-align:left;padding:8px 4px;color:#000}div#navi table{font-size:11pt;text-align:center}div#port table{font-size:11pt;text-align:left}div#port th{background:#ddd;border-bottom:solid 1px;text-align:center}div#port td{background:#eee;padding:0pt 2px;border-bottom:solid 1px;vertical-align:top}div#mio table{font-size:11pt;text-align:center}div#mio th{background:#ddd;border-bottom:solid 1px}div#mio td{background:#eee;padding:0pt 2px;border-bottom:solid 1px;vertical-align:top}.left{text-align:left}</style>
<title>SL9821 - 技術的なはなし - PEGC</title>
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEtUlEQVRYw81XWUiVWxT+JcUEx4ecQjTRFDEfNFA0MBxKE1ESxAFBw0gQLEjM1CA1owcVHwKNNCXQB596cCJxHjGnVDBES01R80pO5XCOfnevxf0Px+GcK+Tl3A0fnH+vtfb+9lprr72OBEDSJaT/AwGdjhMEFhYWUFJSgri4OAQEBCAoKAj37t1DZWUl1tfXVXp7e3sIDQ1FREQEdnd3/5zAwcEBMjMzYWBggCtXriArKws1NTV4//49UlNTYWRkBFNTU5SXl7M+kZGEAwlLS0t/TuDVq1e82PXr1/Hr168TiiMjI0xAT08Pra2t508gODiYFyssLNSoXFFRgZCQEMzMzJw/geLiYl7My8vrSKw1jXMncHh4iNzcXFy8eBFWVlacA6Ojo5wb/ymBrq4udHd3o6enB729vairq8Pjx48RGBiIS5cuwdzcHHfu3MGLFy8wODiIlZUV/Pz5kzc9FwJ9fX3QhurqaqSkpLBX9PX1kZSUxESbm5tVBDo7O/Ht2zcmt729zd48M4FPnz7hLGhvb4e7uztvSNeSboJMoLGx8Yju0NAQJicnuaZsbm5qJSTR9SIkJCTgxo0bGBgYgDx3HBQG2tDV1ZVPLRMgb2iyIYyNjWF+fh5bW1snCUxMTGB8fBz29va8GCUizZ2G2NhY1qGcoDDIBNra2jTaHMf09DR7RUXgy5cvINTW1sLMzAyGhoachHRCWdbU1IT4+HguQo6Ojujo6GBPyQQokWXds4LCo1AoIBEjGXQqqvs2Nja8sIWFBZOijZ2dnZGRkcHeIt3Pnz/zPOlRgtra2p6KtLQ0qO+hDipo0uzsLE4DJRKd/OPHjxzD03RaWlpQX1+vFZQDmvYgSN+/f4cuIVER0SWk1dVVHAddmcXFRZwmIxBzjfIfP/CXkGuyXV5ePvItUVklrK2tIT8/H56enoiKisLt27fh7+/P1ZDkpJydnc3yu3fvIjw8nH8XFRWxfOPrV+wWFEApKuX+s2dQPniAPbHeush2eY+YmBi+wvI3QaLiQEhPT8fVq1f5dPJcQ0MDZzjN5eXlwdraGnNzcyo5JSc9XlVVVVA8fw7lkyfYEo8Uyzc2oBRrKp4+ZfIFghzdGjqYbE+QdnZ2QHBxceH7L3/LuHz5Mt68ecMFysHBgT0lyyhUxsbGePfuHXZEE7Mj3gF1W6XoLQ7v32f7nJwc3Lp1i/sJdR2JigGBHhwPDw92izw3PDyMCxcu4AmdTLAlYycnJzx8+JD1ySOJiYncH8o2DJEHB69fQ9R3KMWbIM9TJaUQqOuq+gFi8+jRI67zVDySk5Nx7do1mJiY4KlwY39/PxcmygOqglS0iISdnR0XFB7UnL59C7ET8OEDxA5H6j5V07CwMO1dMZ1mamqKY/3792+OMTWmxJw65ePDx8eHX0eImEMknshk4JRH518JlJWVwdvbW6yzoRJS4pFHiAh5x83NjUMkD8oBS0tLbuNFkIGXL7W+/VoJUDyoM/b19UV0dDT/J4iMjOT7TmN/f5+fYyJJ15T+D/j5+aG0tBSH1BHdvAnxWECk+0n8Q5ryhey0hkAmo6kXlOVKpfLoJMVfE9TsFMfyQvd/zYRbdAqdj78BYe97ONQ/SskAAAAASUVORK5CYII="><link rel=canonical href=http://www.satotomi.com/sl9821/sl9821_tec5.html></head>
<body>
<p class=title><b>SL9821</b></p>
<table width=100% cellspacing=0><colgroup><col><col>
<tbody><tr>
<td class=empty width=120px><img src='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="122" height="1"><rect fill-opacity="0"/></svg>' style="background-blend-mode:normal!important;background-clip:content-box!important;background-position:50% 50%!important;background-color:rgba(0,0,0,0)!important;background-image:var(--sf-img-1)!important;background-size:100% 100%!important;background-origin:content-box!important;background-repeat:no-repeat!important" width=120 border=0></td>
</tr>
<tr valign=top>
<td class=chapter height=100%>
<table width=100% cellspacing=0 cellpadding=0>
<tbody><tr><td><p><a href=http://www.satotomi.com/sl9821/sl9821.html>はじめに</a></p></tr>
<tr><td><p><a href=http://www.satotomi.com/sl9821/sl9821_dl.html>ダウンロード</a></p></tr>
<tr><td><p><a href=http://www.satotomi.com/sl9821/sl9821_htu.html>使い方</a></p></tr>
<tr><td><p><a href=http://www.satotomi.com/sl9821/sl9821_faq.html>FAQ</a></p></tr>
<tr><td><p><a href=http://www.satotomi.com/sl9821/sl9821_demo.html>実行画面</a></p></tr>
<tr><td><p><a href=http://www.satotomi.com/sl9821/sl9821_tec.html>技術的なはなし</a></p></tr>
<tr><td><p class=s2><a href=http://www.satotomi.com/sl9821/sl9821_tec1.html>プログラム構成</a></p></tr>
<tr><td><p class=s2><a href=http://www.satotomi.com/sl9821/sl9821_tec2.html>CPU</a></p></tr>
<tr><td><p class=s2><a href=http://www.satotomi.com/sl9821/sl9821_tec3.html>テキスト</a></p></tr>
<tr><td><p class=s2><a href=http://www.satotomi.com/sl9821/sl9821_tec4.html>グラフィック</a></p></tr>
<tr><td class=select><p class=s2>PEGC</p></tr>
<tr><td><p class=s2><a href=http://www.satotomi.com/sl9821/sl9821_tec6.html>サウンド</a></p></tr>
</table>
</td>
<td class=content>
<div id=navi>
<table width=100%><colgroup><col width=60><col><col width=60>
<tbody><tr>
<td><a href=http://www.satotomi.com/sl9821/sl9821_tec4.html>前へ</a></td>
<td><h3>技術的なはなし - PEGC</h3></td>
<td><a href=http://www.satotomi.com/sl9821/sl9821_tec6.html>次へ</a></td>
</tr>
</table>
</div>
<p>PEGCは初期のPC-9821(multi、MATE A)に搭載された1677万色中256色の出力が可能な画面モードです。今更どれほどの価値があるものでもないのですが、せっかくですのでここで分かっている範囲の内容にはなりますが、ずいぶん昔に解析して今回のエミュレータ作成においても参考にしたPEGCの機能をここに書いておこうと思います。(一部の内容は、技術評論社「ざべ no124 1993年9月」の記事「PC-9821の拡張機能解析 [第1回]これが「拡張グラフアーキテクチャ」でござ~る」を参考にしています)</p>
<h4>PEGCの概要</h4>
<p>まず、グラフィックV-RAMのサイズは512Kバイトで、画面モードとしては400ライン2画面のほか、480ライン1画面のモードを持ちます。<br>
プログラム的な側面としては、描画の方法として1バイト1パレット情報として扱うパックトピクセルモードと8プレーン同時アクセスでEGCのような描画が可能なプレーンモードの2種類があります。<br>
GDCとの関係ですが、これはエミュレータを作って初めて分かったことですが、GDCのPITCHコマンドに対応しています。Windowsのドライバではこの値に128を設定し横幅を1024ドットとして描画処理をしています(縦横の計算がしやすいから?)。その他、SYNCやRESETコマンドは対応していますが、描画系のコマンドやSCROLL、CSRFORMコマンドなどのコマンドの対応状況は不明です。エミュレータとしての実装は非対応です。<br>
</p>
<h4>使用するポート</h4>
<p>256色モードに関連するポートと設定は以下の通りです。<br>
<div id=port>
<table width=100%><colgroup><col width=80><col width=80><col>
<tbody><tr><th>ポート<th>入出力<th>説明</tr>
<tr><td>6Ah<td>OUT</td>
<td><dl><dt>画面モード切替</dt>
<dd>21h : 拡張(256色)モード<br>
20h : 標準モード<br>
68h : 2画面モード<br>
69h : 1画面モード</dd>
</dl></td>
</tr>
<tr><td>A4h<td>IN/OUT</td>
<td><dl><dt>表示面設定(2画面モードの時のみ有効)</dt>
<dd>00h : VRAMの前半256KByteを表示面として使用<br>
01h : VRAMの後半256KByteを表示面として使用</dd>
</dl></td>
</tr>
<tr><td>A6h<td>OUT</td>
<td><dl><dt>描画面設定(2画面モードの時のみ有効)</dt>
<dd>00h : プレーンモード時の描画面としてVRAMの前半256KByteを使用<br>
01h : プレーンモード時の描画面としてVRAMの後半256KByteを使用</dd>
</dl></td>
</tr>
<tr><td>A8h<td>OUT<td>パレット番号(0255)</tr>
<tr><td>AAh<td>IN/OUT<td>緑の輝度(0255)</tr>
<tr><td>ACh<td>IN/OUT<td>赤の輝度(0255)</tr>
<tr><td>AEh<td>IN/OUT<td>青の輝度(0255)</tr>
<tr><td>09A8h<td>IN/OUT</td>
<td><dl><dt>水平走査線切り替え</dt>
<dd>00h : 24.823KHz(400ライン)<br>
01h : 31.778KHz(480ライン)</dd>
※エミュレータ上で定義している理論値です。<br>
</dl></td>
</tr>
</table>
</div>
<p></p>
<h4>使用するアドレス</h4>
<p>256色モードでも従来のモードで使用するVRAMと同じアドレス領域を使用しますが、使い方がかなり異なります。<br>
<div id=port>
<table width=100%><colgroup><col width=160><col>
<tbody><tr><th>アドレス<th>説明</tr>
<tr><td>A8000hAFFFFh</td>
<td>パックトピクセルモード時にバンク切り替えでVRAMをウインドウ表示させる領域1、バンクの切り替えは後述のE0004hで設定<br>
プレーンモード時にVRAMへアクセスする領域</td>
</tr>
<tr><td>B0000hB7FFFh</td>
<td>パックトピクセルモード時にバンク切り替えでVRAMをウインドウ表示させる領域2、バンクの切り替えは後述のE0006hで設定<br>
プレーンモード時にVRAMへアクセスする領域、1画面モードのときにのみVRAM全体のうちの後半の領域として使用可能</td>
</tr>
<tr><td>B8000hBFFFFh</td>
<td>未使用</td>
</tr>
<tr><td>E0000hE7FFFh<td>メモリマップトIO</tr>
</table>
</div>
<p></p>
<h4>メモリマップトIO</h4>
<p>メモリマップトIOはパックトピクセルモード時のバンク切り替えのページ切り替えと、プレーンモードにおける機能設定のための領域になります。未使用のビットがクリアされることはありますが、基本的に有効なアドレスに対してのリードライトは可能です。<br>
表中の、"-"は書き込んだ後読み込んでも値が反映されていないビット(おそらく機能なし)、"○"は機能がある程度分かっているビット、"?"は書き込んだ値が反映されるものの機能が不明なビットです。"△"は32ビットでVRAMへアクセスするときにのみ有効になるビットです。<br>
また以降、表中のラスタオペレーション等の説明でよく使われる言葉として、<br>
ソースデータとは、CPUからVRAMへ書き込むデータで、設定により直前に読み出したVRAMデータとCPUのデータのいずれかを選択します。シフトバッファを経由するのでシフト設定の影響を受けます。<br>
ディスティネーションデータとは、書き込むアドレスの演算前のVRAMデータのことです。<br>
パターンレジスタは、PEGCの内部データとして持っているデータで、設定によりVRAM読み出し時に更新されます。また、PEGCの場合E0120h以降を参照することでパターンレジスタの内容が確認できます。<br>
<div id=mio>
<table width=100%><colgroup><col width=80><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col width=24><col>
<tbody><tr><th rowspan=2>アドレス<th colspan=16>ビット<th rowspan=2>説明</tr>
<tr><th>15<th>14<th>13<th>12<th>11<th>10<th>9<th>8<th>7<th>6<th>5<th>4<th>3<th>2<th>1<th>0</tr>
<tr><td class=left rowspan=2>E0004h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td><td><td><td></tr>
<tr><td class=left colspan=17>
領域A8000hAFFFFhのバンク指定<br>
512KバイトのVRAM領域を32Kバイト単位に区切った先頭からのインデックス番号を指定、パックトピクセルモードで使用
</tr>
<tr><td class=left rowspan=2>E0006h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td><td><td><td></tr>
<tr><td class=left colspan=17>
領域B0000hB7FFFhのバンク指定<br>
512KバイトのVRAM領域を32Kバイト単位に区切った先頭からのインデックス番号を指定、パックトピクセルモードで使用
</tr>
<tr><td class=left rowspan=2>E0100h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td></tr>
<tr><td class=left colspan=17>
<dl><dt>モード切替</dt>
<dd>0 : パックトピクセルモード<br>
1 : プレーンモードモード</dd>
</dl></tr>
<tr><td class=left rowspan=2>E0102h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>?<td></tr>
<tr><td class=left colspan=17>
<dl><dt>アッパーメモリ領域のVRAM切り替え<br>
<dd>0 : アドレス00F00000h00F80000h、FFF00000hFFF80000hをVRAMとして使用しない<br>
1 : アドレス00F00000h00F80000h、FFF00000hFFF80000hをVRAMとして使用する</dd>
</dl></tr>
<tr><td class=left rowspan=2>E0104h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td><td><td><td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>アクセスプレーン(EGCにおけるポート04A0hに相当)</dt>
<dt>bit 70</dt>
<dd>0 : プレーンへのアクセスは有効<br>
1 : プレーンへのアクセスは無効</dd>
</dl></tr>
<tr><td class=left rowspan=2>E0108h<td><td>?<td><td><td><td><td><td><td><td><td><td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>ラスタオペレーション設定(EGCにおけるポート04A4hに近い機能)</dt>
<dt>bit 15 アドレスE0120h以降の領域で読み出し可能なパターンレジスタのデータ構成を指定</dt>
<dd>0 : プレーン毎に分割した2バイト(4バイト)データ×8プレーン<br>
1 : ピクセル毎に分割した1バイトのデータ×16ピクセル(32ピクセル)<br>
(括弧内はパターンレジスタが更新されるアクセスを32ビットで行った場合)</dd>
<dt>bit 13 パターンレジスタの更新</dt>
<dd>0 : VRAMへアクセスしたときにパターンレジスタを更新しない<br>
1 : VRAMへアクセスしたときにアクセスしたVRAMデータでパターンレジスタを更新する(bit 8が0である必要があります)</dd>
<dt>bit 12 表示方式の設定</dt>
<dd>0 : VRAMへのライトに対しソースデータの値に応じて以下の条件で更新する<br>
<dl><dd>
ソースデータのビットが、<br>
0に対してはアクセスプレーン(E0104h)とディスティネーションデータの論理積(and)<br>
1に対してはアクセスプレーンのnot値とディスティネーションデータの論理和(or)
</dl>
1 : VRAMへのライトはこのレジスタのビット110で決定される描画方法を用いる(以下のビットの説明はbit 12が1のとき)</dd>
bit 11、10 論理演算の方法を指定<br>
<dd>00 : ソースデータとディスティネーションデータとパターンレジスタを使用してラスタオペレーションを行う<br>
ラスタオペレーションの構成はこのレジスタのbit70で指定し、各ビットの意味は以下の通り(EGCと同じ)
<dl><dd>bit 7 : S and D and P<br>
bit 6 : S and D and ~P<br>
bit 5 : S and ~D and P<br>
bit 4 : S and ~D and ~P<br>
bit 3 : ~S and D and P<br>
bit 2 : ~S and D and ~P<br>
bit 1 : ~S and ~D and P<br>
bit 0 : ~S and ~D and ~P<br>
※ここで、Sはソースデータ、Dはディスティネーションデータ、Pはパターンレジスタを表し、~はnot値のこと
</dl>
01 : ソースデータとディスティネーションデータとE0118hで指定されるパレットデータを使用して、ラスタオペレーションを行う
<dl><dd>bit 7 : S and D and C8<br>
bit 6 : S and D and ~C8<br>
bit 5 : S and ~D and C8<br>
bit 4 : S and ~D and ~C8<br>
bit 3 : ~S and D and C8<br>
bit 2 : ~S and D and ~C8<br>
bit 1 : ~S and ~D and C8<br>
bit 0 : ~S and ~D and ~C8<br>
※ここで、Sはソースデータ、Dはディスティネーションデータ、C8はE0118hの値を表し、~はnot値のこと
</dl>
10 : ソースデータとディスティネーションデータとE0114hで指定されるパレットデータを使用して、ラスタオペレーションを行う<br>
参照するカラーパレットが異なるほかは、設定値01と同じ<br>
11 : ソースデータとディスティネーションデータとE0114h、E0118hで指定されるパレットデータを使用して、ラスタオペレーションを行う(EGCには対応する機能がない設定)
<dl><dd>bit 7 : S and D and C4<br>
bit 6 : S and D and ~C4<br>
bit 5 : S and ~D and C4<br>
bit 4 : S and ~D and ~C4<br>
bit 3 : ~S and D and C8<br>
bit 2 : ~S and D and ~C8<br>
bit 1 : ~S and ~D and C8<br>
bit 0 : ~S and ~D and ~C8<br>
※ここで、Sはソースデータ、Dはディスティネーションデータ、C4はE0114hの値、C8はE0118hの値を表し、~はnot値のこと
</dl>
</dd>
<dt>bit 9 シフタの方向設定(EGCのポート04AChのビット12に相当)</dt>
<dd>0 : 右方向(インクリメンタル)シフト<br>
1 : 左方向(デクリメンタル)シフト</dd>
<dt>bit 8 ソースデータの内容</dt>
<dd>0 : 直前に読み出したVRAMデータ<br>
1 : CPUのデータ</dd>
<dt>bit 70 ラスタオペレーションの指定、セットしたビットの演算の論理和が最終的な演算結果になる。詳細は上記bit11、10を参照</dt>
</dl></tr>
<tr><td class=left rowspan=2>E010Ah<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td></tr>
<tr><td class=left colspan=17>
<dl><dt>VRAMをリードしたときに読み出されるデータの選択</dt>
<dt>bit 0</dt>
<dd>0 : 不定値(意味のない値)が読める<br>
1 : 読み出したVRAMのビットがE0114hで指定したカラーパレットと同じ場合は1、異なるときは0になるような値を返す。このときの比較はE0104hのアクセスプレーンの影響を受けるためアクセスプレーンで許可されたプレーンのみチェックされる。またこの機能を有効にするためにはE0108hのビット8が0である必要がある</dd>
</dl><tr><td class=left rowspan=2>E010Ch<td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>マスクレジスタ(EGCにおけるポート04A8hに相当)</dt>
<dt>bit 150(32ビットアクセス時はE010ChからE010Fhまでのbit 310)</dt>
<dd>0 : マスクする(書き込みは無視される)<br>
1 : マスクしない</dd>
</dl></tr>
<tr><td class=left rowspan=2>E0110h<td>-<td>-<td>-<td>-<td><td><td><td><td><td><td><td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>ブロック転送ビット長、転送サイズ-1を設定。最大値は4095(EGCにおけるポート04AEhに相当)</dt>
</dl></tr>
<tr><td class=left rowspan=2>E0112h<td>-<td>-<td>-<td><td><td><td><td><td>-<td>-<td>-<td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>シフタへの読み込み時および書き込み時のシフト数を設定する(EGCにおける04AChのbit74、bit30に相当)</dt>
<dt>なお、表中の上位8ビットへはE0113hへの8ビットアクセスでもリードライト可能(表の都合上ひとまとめで説明しています)</dt>
<dt>bit 11(12)8</dt>
<dd>ライト時のビットシフト数を指定、最大5ビットまで有効でVRAMへ32ビットでライトした場合に5ビット目が有効になる</dd>
<dt>bit 3(4)0</dt>
<dd>リード時のビットシフト数を指定、最大5ビットまで有効でVRAMへ32ビットでリードした場合に5ビット目が有効になる</dd>
</dl></tr>
<tr><td class=left rowspan=2>E0114h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td><td><td><td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>カラーパレット1(EGCにおけるポート04A6h、フォアグラウンドカラーに相当)</dt>
<dt>bit 70</dt>
<dd>カラーパレット番号</dd>
</dl></tr>
<tr><td class=left rowspan=2>E0118h<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td>-<td><td><td><td><td><td><td><td></tr>
<tr><td class=left colspan=17>
<dl><dt>カラーパレット2(EGCにおけるポート04AAh、バックグラウンドカラーに相当)</dt>
<dt>bit 70</dt>
<dd>カラーパレット番号</dd>
</dl></tr>
<tr><td class=left>E0120h<td class=left colspan=17>
<dl><dt>パターンレジスタの内容<br>
この領域はE0108hのbit 15の値により2種類の読み方が出来る<br>
また、パターンレジスタは更新時のメモリアクセスのサイズにより16ビットと32ビットのいずれかのサイズをとる<br>
データは常に4バイトアライメントで配置され、並びかたは以下の通り<br>
・E0108h bit 15 が0のとき、16(32)ドット×8プレーン構成</dt>
<dd>E0120h bit 15(31) 0 プレーン0のビットパターン(以下同様)</dd>
<dd>E0124h bit 15(31) 0 プレーン1</dd>
<dd>E0128h bit 15(31) 0 プレーン2</dd>
<dd>E012Ch bit 15(31) 0 プレーン3</dd>
<dd>E0130h bit 15(31) 0 プレーン4</dd>
<dd>E0134h bit 15(31) 0 プレーン5</dd>
<dd>E0138h bit 15(31) 0 プレーン6</dd>
<dd>E013Ch bit 15(31) 0 プレーン7</dd>
<dt>・E0108h bit 15 が1のとき、1パレットデータ×16(32)ピクセル</dt>
<dd>E0120h bit 7 0 (左から数えて)ピクセル 0のパレット番号(以下同様)</dd>
<dd>E0124h bit 7 0 ピクセル 1</dd>
<dd>E0128h bit 7 0 ピクセル 2</dd>
<dd>E012Ch bit 7 0 ピクセル 3</dd>
<dd>E0130h bit 7 0 ピクセル 4</dd>
<dd>E0134h bit 7 0 ピクセル 5</dd>
<dd>E0138h bit 7 0 ピクセル 6</dd>
<dd>E013Ch bit 7 0 ピクセル 7</dd>
<dd>E0140h bit 7 0 ピクセル 8</dd>
<dd>E0144h bit 7 0 ピクセル 9</dd>
<dd>E0148h bit 7 0 ピクセル 10</dd>
<dd>E014Ch bit 7 0 ピクセル 11</dd>
<dd>E0150h bit 7 0 ピクセル 12</dd>
<dd>E0154h bit 7 0 ピクセル 13</dd>
<dd>E0158h bit 7 0 ピクセル 14</dd>
<dd>E015Ch bit 7 0 ピクセル 15</dd>
<dd>※以降はパターンレジスタが32ビットのとき</dd>
<dd>E0160h bit 7 0 ピクセル 16</dd>
<dd>E0164h bit 7 0 ピクセル 17</dd>
<dd>E0168h bit 7 0 ピクセル 18</dd>
<dd>E016Ch bit 7 0 ピクセル 19</dd>
<dd>E0170h bit 7 0 ピクセル 20</dd>
<dd>E0174h bit 7 0 ピクセル 21</dd>
<dd>E0178h bit 7 0 ピクセル 22</dd>
<dd>E017Ch bit 7 0 ピクセル 23</dd>
<dd>E0180h bit 7 0 ピクセル 24</dd>
<dd>E0184h bit 7 0 ピクセル 25</dd>
<dd>E0188h bit 7 0 ピクセル 26</dd>
<dd>E018Ch bit 7 0 ピクセル 27</dd>
<dd>E0190h bit 7 0 ピクセル 28</dd>
<dd>E0194h bit 7 0 ピクセル 29</dd>
<dd>E0198h bit 7 0 ピクセル 30</dd>
<dd>E019Ch bit 7 0 ピクセル 31</dd>
</dl></tr>
</table>
</div>
<p></p>
<h4>プレーンモードの設定例</h4>
<p>最後に簡単な設定例を例示します。<br>
PEGCのプレーンモードはほぼEGCに対応する機能があるため、EGCと同じように設定することで動作させることが可能です。<br>
前のページでEGCを使って画面全体を2ドット左へシフトするときの設定を例として出しましたが、それと同じことをPEGCのプレーンモードで行うときのことを考えてみます。<br>
まず、EGCのケースを再度確認すると以下のようになっています。<br>
<dl>
<dd>・ポート04A0hにFFF0hを設定、すべてのプレーンへのアクセスを許可<br>
・ポート04A2hに00FFhを設定、フォアグラウンドカラーとバックグラウンドカラーは無効<br>
・ポート04A6hに28F0hを設定、ROPモード、ソースデータはリードしたVRAMデータ、ROPパターンはソースデータのみ<br>
・ポート04A8hにFFFFhを設定、全ビット使用許可(マスクビットなし)<br>
・ポート04AChに0002hを設定、転送方向インクリメンタル、ソースシフト2ビット、ディスティネーションシフト0ビット<br>
・ポート04AEhに637を設定、転送サイズを638ビット<br>
</dl>
これに対し、機能的な対応関係を元にPEGCのプレーンモードの場合を考えると、<br>
<dl>
<dd>・E0100hに0001hを設定、描画モードにプレーンモードを指定<br>
・E0104hにFF00hを設定、すべてのプレーンへのアクセスを許可<br>
・E0108hに10F0hを設定、ROPモードを指定、転送方向インクリメンタル、ソースデータはリードしたVRAMデータ、ROPパターンはソースデータのみ<br>
・E010ChにFFFFhを設定、全ビット使用許可(マスクビットなし)<br>
・E0110hに637を設定、転送サイズを638ビット<br>
・E0112hに0002hを設定、ソースシフト2ビット、ディスティネーションシフト0ビット<br>
</dl>
以上のような設定になります。なお、ROPの結果ライトされるのはソースデータのみなので、E0108hのbit11、10に関しては値を変えても結果は変わりません。<br>
VRAMへのアクセスの注意点はEGCと同じで、最初の手順としてオフセット0のリード、オフセット2のリード、オフセット0へのライト、以降オフセットをずらしながらリードとライトを繰り返すという手順は同じです。違う点としては、PEGCは32ビットアクセスが可能なので32ビットでアクセスすればより高速に処理が実行できます。<br>
余談ですが、画面を左へシフトする処理としては、転送方向をデクリメンタル、ソースシフトを0ビット、ディスティネーションシフトを2ビットに設定し、画面の右側からアドレスをデクリメントしながら転送処理をするという方法でも実現可能です。この場合はリードとライトは初めから交互に同じオフセットに対して行います。インクリメンタルな方向での実現方法を例に取り上げたのは、シフトバッファがアンダーフロー状態になりうることとその対処方法についての説明のためです。<br>
<p></p>
<br>
<div id=navi>
<p align=center>Copyright ©satotomi 2017</p>
<table width=100%><colgroup><col width=60><col><col width=60>
<tbody><tr>
<td><a href=http://www.satotomi.com/sl9821/sl9821_tec4.html>前へ</a></td>
<td></td>
<td><a href=http://www.satotomi.com/sl9821/sl9821_tec6.html>次へ</a></td>
</tr>
</table>
</div>
</td>
</table>

View File

@@ -0,0 +1,635 @@
#include "compiler.h"
// PEGC 256 color mode
// 詳しくもないのに作ったのでかなりいい加減です。
// 改良するのであれば全部捨てて作り直した方が良いかもしれません
#if defined(SUPPORT_PC9821)
#include "cpucore.h"
#include "pccore.h"
#include "iocore.h"
#include "memvga.h"
#include "vram.h"
// ---- macros
#define VGARD8(p, a) { \
UINT32 addr; \
addr = (vramop.mio1[(p) * 2] & 15) << 15; \
addr += (a); \
addr -= (0xa8000 + ((p) * 0x8000)); \
return(vramex[addr]); \
}
#define VGAWR8(p, a, v) { \
UINT32 addr; \
UINT8 bit; \
addr = (vramop.mio1[(p) * 2] & 15) << 15; \
addr += (a); \
addr -= (0xa8000 + ((p) * 0x8000)); \
vramex[addr] = (v); \
bit = (addr & 0x40000)?2:1; \
vramupdate[LOW15(addr >> 3)] |= bit; \
gdcs.grphdisp |= bit; \
}
#define VGARD16(p, a) { \
UINT32 addr; \
addr = (vramop.mio1[(p) * 2] & 15) << 15; \
addr += (a); \
addr -= (0xa8000 + ((p) * 0x8000)); \
return(LOADINTELWORD(vramex + addr)); \
}
#define VGAWR16(p, a, v) { \
UINT32 addr; \
UINT8 bit; \
addr = (vramop.mio1[(p) * 2] & 15) << 15; \
addr += (a); \
addr -= (0xa8000 + ((p) * 0x8000)); \
STOREINTELWORD(vramex + addr, (v)); \
bit = (addr & 0x40000)?2:1; \
vramupdate[LOW15((addr + 0) >> 3)] |= bit; \
vramupdate[LOW15((addr + 1) >> 3)] |= bit; \
gdcs.grphdisp |= bit; \
}
// ---- flat (PEGC 0F00000h-00F80000h Memory Access ?)
REG8 MEMCALL memvgaf_rd8(UINT32 address) {
return(vramex[address & 0x7ffff]);
}
void MEMCALL memvgaf_wr8(UINT32 address, REG8 value) {
UINT8 bit;
address = address & 0x7ffff;
vramex[address] = value;
bit = (address & 0x40000)?2:1;
vramupdate[LOW15(address >> 3)] |= bit;
gdcs.grphdisp |= bit;
}
REG16 MEMCALL memvgaf_rd16(UINT32 address) {
address = address & 0x7ffff;
return(LOADINTELWORD(vramex + address));
}
void MEMCALL memvgaf_wr16(UINT32 address, REG16 value) {
UINT8 bit;
address = address & 0x7ffff;
STOREINTELWORD(vramex + address, value);
bit = (address & 0x40000)?2:1;
vramupdate[LOW15((address + 0) >> 3)] |= bit;
vramupdate[LOW15((address + 1) >> 3)] |= bit;
gdcs.grphdisp |= bit;
}
UINT32 MEMCALL memvgaf_rd32(UINT32 address){
return (UINT32)memvgaf_rd16(address)|(memvgaf_rd16(address+2)<<16);
}
void MEMCALL memvgaf_wr32(UINT32 address, UINT32 value){
memvgaf_wr16(address, (REG16)value);
memvgaf_wr16(address+2, (REG16)(value >> 16));
}
// ---- 8086 bank memory (PEGC memvga0:A8000h-AFFFFh, memvga1:B0000h-B7FFFh Bank(Packed-pixel Mode) or Plane Access(Plane Mode))
REG8 MEMCALL memvga0_rd8(UINT32 address){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
return 0;
}else
#endif
{
// Packed-pixel Mode
VGARD8(0, address)
}
}
REG8 MEMCALL memvga1_rd8(UINT32 address){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
return 0;
}else
#endif
{
// Packed-pixel Mode
VGARD8(1, address)
}
}
void MEMCALL memvga0_wr8(UINT32 address, REG8 value){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
// Nothing to do
}else
#endif
{
// Packed-pixel Mode
VGAWR8(0, address, value)
}
}
void MEMCALL memvga1_wr8(UINT32 address, REG8 value){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
// Nothing to do
}else
#endif
{
// Packed-pixel Mode
VGAWR8(1, address, value)
}
}
REG16 MEMCALL memvga0_rd16(UINT32 address){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
return pegc_memvgaplane_rd16(address);
}else
#endif
{
// Packed-pixel Mode
VGARD16(0, address)
}
}
REG16 MEMCALL memvga1_rd16(UINT32 address){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
return pegc_memvgaplane_rd16(address);
}else
#endif
{
// Packed-pixel Mode
VGARD16(1, address)
}
}
void MEMCALL memvga0_wr16(UINT32 address, REG16 value){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
pegc_memvgaplane_wr16(address, value);
}else
#endif
{
// Packed-pixel Mode
VGAWR16(0, address, value)
}
}
void MEMCALL memvga1_wr16(UINT32 address, REG16 value){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
pegc_memvgaplane_wr16(address, value);
}else
#endif
{
// Packed-pixel Mode
VGAWR16(1, address, value)
}
}
UINT32 MEMCALL memvga0_rd32(UINT32 address){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
return pegc_memvgaplane_rd32(address);
}else
#endif
{
// Packed-pixel Mode
return (UINT32)memvga0_rd16(address)|(memvga0_rd16(address+2)<<16);
}
}
UINT32 MEMCALL memvga1_rd32(UINT32 address){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
return pegc_memvgaplane_rd32(address);
}else
#endif
{
// Packed-pixel Mode
return (UINT32)memvga1_rd16(address)|(memvga1_rd16(address+2)<<16);
}
}
void MEMCALL memvga0_wr32(UINT32 address, UINT32 value){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
pegc_memvgaplane_wr32(address, value);
}else
#endif
{
// Packed-pixel Mode
memvga0_wr16(address, (REG16)value);
memvga0_wr16(address+2, (REG16)(value >> 16));
}
}
void MEMCALL memvga1_wr32(UINT32 address, UINT32 value){
#ifdef SUPPORT_PEGC
if(pegc.enable && (vramop.mio2[PEGC_REG_MODE] & 0x1)){
// Plane Mode
pegc_memvgaplane_wr32(address, value);
}else
#endif
{
// Packed-pixel Mode
memvga1_wr16(address, (REG16)value);
memvga1_wr16(address+2, (REG16)(value >> 16));
}
}
// ---- 8086 bank I/O (PEGC E0000h-E7FFFh MMIO)
REG8 MEMCALL memvgaio_rd8(UINT32 address) {
UINT pos;
if(address > 0xe0000 + 0x0100){
UINT pos;
REG8 ret;
pos = address - 0xe0000 - 0x0100;
if(PEGC_REG_PATTERN <= pos){
ret = 0;
// vramop.mio2[PEGC_REG_PATTERN + ofs] PATTERN DATA (16bit)
// pix15 pix14 ... pix1 pix0
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane0 |<--- ofs = 01h --->|<--- ofs = 00h --->|
// (bit0) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane1 |<--- ofs = 05h --->|<--- ofs = 04h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane2 |<--- ofs = 09h --->|<--- ofs = 08h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane3 |<--- ofs = 0Dh --->|<--- ofs = 0Ch --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane4 |<--- ofs = 11h --->|<--- ofs = 10h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane5 |<--- ofs = 15h --->|<--- ofs = 14h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane6 |<--- ofs = 19h --->|<--- ofs = 18h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane7 |<--- ofs = 1Dh --->|<--- ofs = 1Ch --->|
// (bit7) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
if(vramop.mio2[PEGC_REG_PLANE_ROP] & 0x8000){
// 1 palette x 16 pixels
// bit8 〜 bit0
// pix0 <-- E0120h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit0)
// pix1 <-- E0124h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit1)
// pix2 <-- E0128h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit2)
// pix3 <-- E012Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit3)
// pix4 <-- E0130h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit4)
// pix5 <-- E0134h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit5)
// pix6 <-- E0138h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit6)
// pix7 <-- E013Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit7)
// pix8 <-- E0140h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit8)
// pix9 <-- E0144h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit9)
// pix10<-- E0148h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit10)
// pix11<-- E014Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit11)
// pix12<-- E0150h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit12)
// pix13<-- E0154h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit13)
// pix14<-- E0158h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit14)
// pix15<-- E015Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit15)
if((pos & 0x3)==0 && pos < 0x60){
int i;
int bit = pos / 4;
for(i=7;i>=0;i--){
ret |= (vramop.mio2[PEGC_REG_PATTERN + i*4] >> bit) & 0x1;
ret <<= 1;
}
}
}else{
// 16 pixels x 8 planes
// pix15 〜 pix0
// bit0 <-- E0120h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x00]
// bit1 <-- E0124h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x04]
// bit2 <-- E0128h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x08]
// bit3 <-- E012Ch(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x0C]
// bit4 <-- E0130h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x10]
// bit5 <-- E0134h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x14]
// bit6 <-- E0138h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x18]
// bit7 <-- E013Ch(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C]
if((pos & 0x3)==0 && pos < 0x40){
ret = vramop.mio2[pos];
}
}
return ret;
}
}
address -= 0xe0000;
pos = address - 0x0004;
if (pos < 4) {
return(vramop.mio1[pos]);
}
pos = address - 0x0100;
if (pos < 0x20) {
return(vramop.mio2[pos]);
}
return(0x00);
}
void MEMCALL memvgaio_wr8(UINT32 address, REG8 value) {
UINT pos;
if(address > 0xe0000 + 0x0100){
UINT pos;
pos = address - 0xe0000 - 0x0100;
if(PEGC_REG_PATTERN <= pos){
if(vramop.mio2[PEGC_REG_PLANE_ROP] & 0x8000){
// 1 palette x 8 pixels
if((pos & 0x3)==0 && pos < 0x60){
int i;
int bit = pos / 4;
for(i=0;i<7;i++){
UINT8 tmp = vramop.mio2[PEGC_REG_PATTERN + i*4];
tmp = (tmp & ~(1 << bit)) | ((value & 1) << bit);
vramop.mio2[PEGC_REG_PATTERN + i*4] = tmp;
value >>= 1;
}
}
}else{
// 8 pixels x 8 planes
if((pos & 0x3)==0 && pos < 0x40){
vramop.mio2[pos] = value;
}
}
return;
}
}
////if(address == 0xE0110 || address == 0xE0108){
// pegc.remain = 0;
// //pegc.lastdatalen = 0;
// pegc.lastdatalen = -(SINT32)((LOADINTELWORD(vramop.mio2+PEGC_REG_SHIFT)) & 0x1f);
////}
address -= 0xe0000;
pos = address - 0x0004;
if (pos < 4) {
vramop.mio1[pos] = value;
return;
}
pos = address - 0x0100;
if (pos < 0x20) {
vramop.mio2[pos] = value;
return;
}
}
REG16 MEMCALL memvgaio_rd16(UINT32 address) {
REG16 ret;
if(address > 0xe0000 + 0x0100){
UINT pos;
pos = address - 0xe0000 - 0x0100;
if(PEGC_REG_PATTERN <= pos){
ret = 0;
// vramop.mio2[PEGC_REG_PATTERN + ofs] PATTERN DATA (16bit)
// pix15 pix14 ... pix1 pix0
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane0 |<--- ofs = 01h --->|<--- ofs = 00h --->|
// (bit0) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane1 |<--- ofs = 05h --->|<--- ofs = 04h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane2 |<--- ofs = 09h --->|<--- ofs = 08h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane3 |<--- ofs = 0Dh --->|<--- ofs = 0Ch --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane4 |<--- ofs = 11h --->|<--- ofs = 10h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane5 |<--- ofs = 15h --->|<--- ofs = 14h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane6 |<--- ofs = 19h --->|<--- ofs = 18h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane7 |<--- ofs = 1Dh --->|<--- ofs = 1Ch --->|
// (bit7) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
if(vramop.mio2[PEGC_REG_PLANE_ROP] & 0x8000){
// 1 palette x 16 pixels
// bit8 〜 bit0
// pix0 <-- E0120h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit0)
// pix1 <-- E0124h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit1)
// pix2 <-- E0128h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit2)
// pix3 <-- E012Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit3)
// pix4 <-- E0130h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit4)
// pix5 <-- E0134h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit5)
// pix6 <-- E0138h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit6)
// pix7 <-- E013Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit7)
// pix8 <-- E0140h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit8)
// pix9 <-- E0144h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit9)
// pix10<-- E0148h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit10)
// pix11<-- E014Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit11)
// pix12<-- E0150h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit12)
// pix13<-- E0154h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit13)
// pix14<-- E0158h(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit14)
// pix15<-- E015Ch(8bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit15)
if((pos & 0x3)==0 && pos < 0x60){
int i;
int bit = pos / 4;
for(i=7;i>=0;i--){
ret |= (LOADINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + i*4) >> bit) & 0x1;
ret <<= 1;
}
}
}else{
// 16 pixels x 8 planes
// pix15 〜 pix0
// bit0 <-- E0120h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x00]
// bit1 <-- E0124h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x04]
// bit2 <-- E0128h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x08]
// bit3 <-- E012Ch(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x0C]
// bit4 <-- E0130h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x10]
// bit5 <-- E0134h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x14]
// bit6 <-- E0138h(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x18]
// bit7 <-- E013Ch(16bit) --> LOADINTELWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C]
if((pos & 0x3)==0 && pos < 0x40){
ret = LOADINTELWORD(vramop.mio2 + pos);
}
}
return ret;
}
}
ret = memvgaio_rd8(address);
ret |= memvgaio_rd8(address + 1) << 8;
return(ret);
}
void MEMCALL memvgaio_wr16(UINT32 address, REG16 value) {
if(address > 0xe0000 + 0x0100){
UINT pos;
pos = address - 0xe0000 - 0x0100;
if(PEGC_REG_PATTERN <= pos){
if(vramop.mio2[PEGC_REG_PLANE_ROP] & 0x8000){
// 1 palette x 16 pixels
if((pos & 0x3)==0 && pos < 0x60){
int i;
int bit = pos / 4;
for(i=0;i<7;i++){
UINT16 tmp = LOADINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + i*4);
tmp = (tmp & ~(1 << bit)) | ((value & 1) << bit);
STOREINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + i*4, tmp);
value >>= 1;
}
}
}else{
// 16 pixels x 8 planes
if((pos & 0x3)==0 && pos < 0x40){
STOREINTELWORD(vramop.mio2 + pos, value);
}
}
return;
}
}
memvgaio_wr8(address + 0, (REG8)value);
memvgaio_wr8(address + 1, (REG8)(value >> 8));
}
UINT32 MEMCALL memvgaio_rd32(UINT32 address){
UINT32 ret;
UINT pos;
pos = address - 0xe0000 - 0x0100;
if(address > 0xe0000 + 0x0100 && PEGC_REG_PATTERN <= pos){
ret = 0;
// vramop.mio2[PEGC_REG_PATTERN + ofs] PATTERN DATA (32bit)
// pix31 pix30 ... pix1 pix0
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane0 |<--- ofs = 03h --->|<--- ofs = 02h --->|<--- ofs = 01h --->|<--- ofs = 00h --->|
// (bit0) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane1 |<--- ofs = 07h --->|<--- ofs = 06h --->|<--- ofs = 05h --->|<--- ofs = 04h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane2 |<--- ofs = 0Bh --->|<--- ofs = 0Ah --->|<--- ofs = 09h --->|<--- ofs = 08h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane3 |<--- ofs = 0Fh --->|<--- ofs = 0Eh --->|<--- ofs = 0Dh --->|<--- ofs = 0Ch --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane4 |<--- ofs = 13h --->|<--- ofs = 12h --->|<--- ofs = 11h --->|<--- ofs = 10h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane5 |<--- ofs = 17h --->|<--- ofs = 16h --->|<--- ofs = 15h --->|<--- ofs = 14h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane6 |<--- ofs = 1Bh --->|<--- ofs = 1Ah --->|<--- ofs = 19h --->|<--- ofs = 18h --->|
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// plane7 |<--- ofs = 1Fh --->|<--- ofs = 1Eh --->|<--- ofs = 1Dh --->|<--- ofs = 1Ch --->|
// (bit7) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
if(vramop.mio2[PEGC_REG_PLANE_ROP] & 0x8000){
// 1 palette x 32 pixels
// bit8 〜 bit0
// pix0 <-- E0120h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit0)
// pix1 <-- E0124h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit1)
// pix2 <-- E0128h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit2)
// pix3 <-- E012Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit3)
// pix4 <-- E0130h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit4)
// pix5 <-- E0134h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit5)
// pix6 <-- E0138h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit6)
// pix7 <-- E013Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit7)
// pix8 <-- E0140h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit8)
// pix9 <-- E0144h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit9)
// pix10<-- E0148h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit10)
// pix11<-- E014Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit11)
// pix12<-- E0150h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit12)
// pix13<-- E0154h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit13)
// pix14<-- E0158h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit14)
// pix15<-- E015Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit15)
// pix16<-- E0160h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit16)
// pix17<-- E0164h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit17)
// pix18<-- E0168h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit18)
// pix19<-- E016Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit19)
// pix20<-- E0170h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit20)
// pix21<-- E0174h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit21)
// pix22<-- E0178h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit22)
// pix23<-- E017Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit23)
// pix24<-- E0180h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit24)
// pix25<-- E0184h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit25)
// pix26<-- E0188h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit26)
// pix27<-- E018Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit27)
// pix28<-- E0190h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit28)
// pix29<-- E0194h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit29)
// pix30<-- E0198h(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit30)
// pix31<-- E019Ch(8bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C], vramop.mio2[PEGC_REG_PATTERN + 0x18], ... , vramop.mio2[PEGC_REG_PATTERN + 0x00] (bit31)
if((pos & 0x3)==0 && pos < 0x100){
int i;
int bit = pos / 4;
for(i=7;i>=0;i--){
ret |= (LOADINTELDWORD(vramop.mio2 + PEGC_REG_PATTERN + i*4) >> bit) & 0x1;
ret <<= 1;
}
}
}else{
// 32 pixels x 8 planes
// pix31 〜 pix0
// bit0 <-- E0120h(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x00]
// bit1 <-- E0124h(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x04]
// bit2 <-- E0128h(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x08]
// bit3 <-- E012Ch(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x0C]
// bit4 <-- E0130h(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x10]
// bit5 <-- E0134h(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x14]
// bit6 <-- E0138h(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x18]
// bit7 <-- E013Ch(32bit) --> LOADINTELDWORD vramop.mio2[PEGC_REG_PATTERN + 0x1C]
if((pos & 0x3)==0 && pos < 0x40){
ret = LOADINTELDWORD(vramop.mio2 + pos);
}
}
return ret;
}
return (UINT32)memvgaio_rd16(address)|(memvgaio_rd16(address+2)<<16);
}
void MEMCALL memvgaio_wr32(UINT32 address, UINT32 value){
UINT pos;
pos = address - 0xe0000 - 0x0100;
if(address > 0xe0000 + 0x0100 && PEGC_REG_PATTERN <= pos){
if(vramop.mio2[PEGC_REG_PLANE_ROP] & 0x8000){
// 1 palette x 32 pixels
if((pos & 0x3)==0 && pos < 0x100){
int i;
int bit = pos / 4;
for(i=0;i<7;i++){
UINT32 tmp = LOADINTELDWORD(vramop.mio2 + PEGC_REG_PATTERN + i*4);
tmp = (tmp & ~(1 << bit)) | ((value & 1) << bit);
STOREINTELDWORD(vramop.mio2 + PEGC_REG_PATTERN + i*4, tmp);
value >>= 1;
}
}
}else{
// 32 pixels x 8 planes
if((pos & 0x3)==0 && pos < 0x40){
STOREINTELDWORD(vramop.mio2 + pos, value);
}
}
return;
}
memvgaio_wr16(address, (REG16)value);
memvgaio_wr16(address+2, (REG16)(value >> 16));
}
#endif

View File

@@ -0,0 +1,335 @@
#include "compiler.h"
#include "cpucore.h"
#include "pccore.h"
#include "iocore.h"
#include "memegc.h"
#include "vram.h"
// PEGC プレーンモード
// 関連: vram.c, vram.h, memvga.c, memvga.h
// 詳しくもないのに作ったのでかなりいい加減です。
// 改良するのであれば全部捨てて作り直した方が良いかもしれません
#ifdef SUPPORT_PEGC
//
REG16 MEMCALL pegc_memvgaplane_rd16(UINT32 address){
int i,j;
UINT16 ret = 0;
//UINT8 bit;
UINT32 addr; // 画素単位の読み込み元アドレス
//UINT8 src, dst, pat1, pat2; // ソースデータ、ディスティネーションデータ、パターンデータ1&2
UINT8 ropcode = 0; // ラスタオペレーション設定 E0108h bit0〜bit7
UINT8 ropmethod = 0; // 論理演算の方法を指定(パターンレジスタまたはカラーパレット) E0108h bit11,10
UINT8 ropupdmode = 0; // 1ならラスタオペレーションを使用 E0108h bit12
UINT8 planemask = 0; // プレーン書き込み禁止(0=許可, 1=禁止) E0104h
UINT32 pixelmask = 0; // ビット(画素)への書き込み禁止(0=禁止, 1=許可) E010Ch
UINT32 bitlength = 0; // ブロック転送ビット長(転送サイズ-1) E0110h
UINT32 srcbitshift = 0; // リード時のビットシフト数 E0112h
UINT8 shiftdir = 1; // シフト方向0:inc, 1:decE0108h bit9
UINT8 srccpu = 1; // 直前に読み取ったVRAMデータではなくCPUデータを使用するか E0108h bit8
// PEGCレジスタ読みだし
ropcode = LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) & 0xff;
ropmethod = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 10) & 0x3;
ropupdmode = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 12) & 0x1;
planemask = vramop.mio2[PEGC_REG_PLANE_ACCESS];
pixelmask = LOADINTELDWORD(vramop.mio2 + PEGC_REG_MASK);
bitlength = LOADINTELDWORD(vramop.mio2 + PEGC_REG_LENGTH) & 0x0fff;
srcbitshift = (LOADINTELWORD(vramop.mio2+PEGC_REG_SHIFT)) & 0x1f;
shiftdir = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 9) & 0x1;
srccpu = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 8) & 0x1;
// 画素単位のアドレス計算
addr = (address - 0xa8000) * 8;
addr += srcbitshift;
addr &= 0x80000-1; // 安全のため
if(!srccpu){
if(!shiftdir){
for(i=0;i<16;i++){
UINT32 addrtmp = (addr + i) & (0x80000-1); // 読み取り位置
UINT32 pixmaskpos = (1 << ((15-i+8)&0xf)); // 現在の画素に対応するpixelmaskのビット位置
UINT8 data = vramex[addrtmp];
// compare data
if((data ^ vramop.mio2[PEGC_REG_PALETTE1]) & ~planemask){
ret |= (1<<i);
}
// update last data
pegc.lastdata[i] = data;
// update pattern reg
if((LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 13) & 0x1){
for(j=7;j>=0;j--){
UINT16 regdata = LOADINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + j*4);
regdata = (regdata & ~(1 << i)) | (((data >> j) & 0x1) << i);
STOREINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + j*4, regdata);
}
}
}
}else{
for(i=0;i<16;i++){
UINT32 addrtmp = (addr - i) & (0x80000-1); // 読み取り位置
UINT32 pixmaskpos = (1 << ((i/8)*8 + (7-(i&0x7)))); // 現在の画素に対応するvalueやpixelmaskのビット位置
UINT8 data = vramex[addrtmp];
// compare data
if((data ^ vramop.mio2[PEGC_REG_PALETTE1]) & ~planemask){
ret |= (1<<i);
}
// update last data
pegc.lastdata[i] = data;
// update pattern reg
if(LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) & 0x2000){
for(j=7;j>=0;j--){
UINT16 regdata = LOADINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + j*4);
regdata = (regdata & ~(1 << i)) | (((data >> j) & 0x1) << i);
STOREINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + j*4, regdata);
}
}
}
}
}
pegc.lastdatalen += 16;
return ret;
}
void MEMCALL pegc_memvgaplane_wr16(UINT32 address, REG16 value){
int i,j;
UINT8 bit;
UINT32 addr; // 画素単位の書き込み先アドレス
UINT8 src, dst, pat1, pat2; // ソースデータ、ディスティネーションデータ、パターンデータ1&2
UINT8 ropcode = 0; // ラスタオペレーション設定 E0108h bit0〜bit7
UINT8 ropmethod = 0; // 論理演算の方法を指定(パターンレジスタまたはカラーパレット) E0108h bit11,10
UINT8 ropupdmode = 0; // 1ならラスタオペレーションを使用 E0108h bit12
UINT8 planemask = 0; // プレーン書き込み禁止(0=許可, 1=禁止) E0104h
UINT32 pixelmask = 0; // ビット(画素)への書き込み禁止(0=禁止, 1=許可) E010Ch
UINT32 bitlength = 0; // ブロック転送ビット長(転送サイズ-1) E0110h
UINT32 dstbitshift = 0; // ライト時のビットシフト数 E0112h
UINT8 shiftdir = 1; // シフト方向0:inc, 1:decE0108h bit9
UINT8 srccpu = 1; // 直前に読み取ったVRAMデータではなくCPUデータを使用するか E0108h bit8
// PEGCレジスタ読みだし
ropcode = LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) & 0xff;
ropmethod = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 10) & 0x3;
ropupdmode = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 12) & 0x1;
planemask = vramop.mio2[PEGC_REG_PLANE_ACCESS];
pixelmask = LOADINTELDWORD(vramop.mio2 + PEGC_REG_MASK);
bitlength = LOADINTELDWORD(vramop.mio2 + PEGC_REG_LENGTH) & 0x0fff;
dstbitshift = (LOADINTELWORD(vramop.mio2+PEGC_REG_SHIFT) >> 8) & 0x1f;
shiftdir = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 9) & 0x1;
srccpu = (LOADINTELWORD(vramop.mio2+PEGC_REG_PLANE_ROP) >> 8) & 0x1;
// 画素単位のアドレス計算
addr = (address - 0xa8000) * 8;
addr += dstbitshift;
addr &= 0x80000-1; // 安全のため
// ???
bit = (addr & 0x40000)?2:1;
//if(!srccpu && pegc.remain!=0 && pegc.lastdatalen < 16){
// return; // 書き込み無視
//}
if(pegc.remain == 0){
// データ数戻す?
pegc.remain = (LOADINTELDWORD(vramop.mio2 + PEGC_REG_LENGTH) & 0x0fff) + 1;
}
if(!shiftdir){
// とりあえずインクリメンタル
// メモ (なんかおかしい)
// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
// i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
// value → bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 bitF bitE bitD bitC bitB bitA bit9 bit8
// pixelmask→ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 bitF bitE bitD bitC bitB bitA bit9 bit8 planemask SRC,DST,PAT
// ↓ ↓
// plane0 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit0 bit0
// plane1 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit1 bit1
// plane2 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit2 bit2
// plane3 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit3 bit3
// plane4 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit4 bit4
// plane5 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit5 bit5
// plane6 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit6 bit6
// plane7 vramex[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] bit7 bit7
for(i=0;i<16;i++){
UINT32 addrtmp = (addr + i) & (0x80000-1); // 書き込み位置
UINT32 pixmaskpos = (1 << ((i/8)*8 + (7-(i&0x7)))); // 現在の画素に対応するvalueやpixelmaskのビット位置
if(pixelmask & pixmaskpos){ // 書き込み禁止チェック
// SRCの設定
if(srccpu){
// CPUデータを使う
src = (value & pixmaskpos) ? 0xff : 0x00;
}else{
// 直前に読み取ったVRAMデータを使う
src = pegc.lastdata[i];
}
// DSTの設定 現在のVRAMデータ取得
dst = vramex[addrtmp];
if(ropupdmode){
// ROP使用
vramex[addrtmp] = (vramex[addrtmp] & planemask); // 書き換えされる予定のビットを0にしておく
// PATの設定
if(ropmethod==0){
// パターンレジスタを使用
int col = 0;
for(j=7;j>=0;j--){
col |= (LOADINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + j*4) >> i) & 0x1;
col <<= 1;
}
pat1 = pat2 = col;
}else if(ropmethod==1){
// パレット2を使用
pat1 = pat2 = vramop.mio2[PEGC_REG_PALETTE2];
}else if(ropmethod==2){
// パレット1を使用
pat1 = pat2 = vramop.mio2[PEGC_REG_PALETTE1];
}else if(ropmethod==3){
// パレット1と2を使用
pat1 = vramop.mio2[PEGC_REG_PALETTE1];
pat2 = vramop.mio2[PEGC_REG_PALETTE2];
}
// ROP実行
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<7)) vramex[addrtmp] |= (src & dst & pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<6)) vramex[addrtmp] |= (src & dst & ~pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<5)) vramex[addrtmp] |= (src & ~dst & pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<4)) vramex[addrtmp] |= (src & ~dst & ~pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<3)) vramex[addrtmp] |= (~src & dst & pat2) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<2)) vramex[addrtmp] |= (~src & dst & ~pat2) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<1)) vramex[addrtmp] |= (~src & ~dst & pat2) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<0)) vramex[addrtmp] |= (~src & ~dst & ~pat2) & (~planemask);
}else{
// SRCの0に対してplanemask&DST, 1に対して~planemask|DST
vramex[addrtmp] = 0;
for(j=0;j<8;j++){
if(src & (1<<j)){
vramex[addrtmp] |= (~planemask | dst) & (1<<j);
}else{
vramex[addrtmp] |= (planemask & dst) & (1<<j);
}
}
}
// ???
vramupdate[LOW15(addrtmp >> 3)] |= bit;
}
pegc.remain--;
// 転送サイズチェック
if(pegc.remain == 0){
goto endloop; // 抜ける
}
}
}else{
for(i=0;i<16;i++){
UINT32 addrtmp = (addr - i) & (0x80000-1); // 書き込み位置
UINT32 pixmaskpos = (1 << ((i/8)*8 + (7-(i&0x7)))); // 現在の画素に対応するvalueやpixelmaskのビット位置
if(pixelmask & pixmaskpos){ // 書き込み禁止チェック
// SRCの設定
if(srccpu){
// CPUデータを使う
src = (value & pixmaskpos) ? 0xff : 0x00;
}else{
// 直前に読み取ったVRAMデータを使う
src = pegc.lastdata[i];
}
// DSTの設定 現在のVRAMデータ取得
dst = vramex[addrtmp];
if(ropupdmode){
// ROP使用
vramex[addrtmp] = (vramex[addrtmp] & planemask); // 書き換えされる予定のビットを0にしておく
// PATの設定
if(ropmethod==0){
// パターンレジスタを使用
int col = 0;
for(j=7;j>=0;j--){
col |= (LOADINTELWORD(vramop.mio2 + PEGC_REG_PATTERN + j*4) >> i) & 0x1;
col <<= 1;
}
pat1 = pat2 = col;
}else if(ropmethod==1){
// パレット2を使用
pat1 = pat2 = vramop.mio2[PEGC_REG_PALETTE2];
}else if(ropmethod==2){
// パレット1を使用
pat1 = pat2 = vramop.mio2[PEGC_REG_PALETTE1];
}else if(ropmethod==3){
// パレット1と2を使用
pat1 = vramop.mio2[PEGC_REG_PALETTE1];
pat2 = vramop.mio2[PEGC_REG_PALETTE2];
}
// ROP実行
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<7)) vramex[addrtmp] |= (src & dst & pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<6)) vramex[addrtmp] |= (src & dst & ~pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<5)) vramex[addrtmp] |= (src & ~dst & pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<4)) vramex[addrtmp] |= (src & ~dst & ~pat1) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<3)) vramex[addrtmp] |= (~src & dst & pat2) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<2)) vramex[addrtmp] |= (~src & dst & ~pat2) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<1)) vramex[addrtmp] |= (~src & ~dst & pat2) & (~planemask);
if(vramop.mio2[PEGC_REG_PLANE_ROP] & (1<<0)) vramex[addrtmp] |= (~src & ~dst & ~pat2) & (~planemask);
}else{
// SRCの0に対してplanemask&DST, 1に対して~planemask|DST
vramex[addrtmp] = 0;
for(j=0;j<8;j++){
if(src & (1<<j)){
vramex[addrtmp] |= (~planemask | dst) & (1<<j);
}else{
vramex[addrtmp] |= (planemask & dst) & (1<<j);
}
}
}
// ???
vramupdate[LOW15(addrtmp >> 3)] |= bit;
}
pegc.remain--;
// 転送サイズチェック
if(pegc.remain == 0){
goto endloop; // 抜ける
}
}
}
endloop:
gdcs.grphdisp |= bit;
pegc.lastdatalen -= 16;
}
UINT32 MEMCALL pegc_memvgaplane_rd32(UINT32 address){
// TODO: 作る
return 0;
}
void MEMCALL pegc_memvgaplane_wr32(UINT32 address, UINT32 value){
// TODO: 作る
}
void pegc_reset(const NP2CFG *pConfig) {
ZeroMemory(&pegc, sizeof(pegc));
pegc.enable = np2cfg.usepegcplane;
(void)pConfig;
}
void pegc_bind(void) {
}
#endif

View File

@@ -0,0 +1,48 @@
#pragma once
#ifdef SUPPORT_PEGC
#define PEGC_REG_PPM_BANK_A8 0x000 // mio1 E0004h
#define PEGC_REG_PPM_BANK_B0 0x002 // mio1 E0006h
#define PEGC_REG_MODE 0x000 // mio2 E0100h
#define PEGC_REG_VRAM_ENABLE 0x002 // mio2 E0102h
#define PEGC_REG_PLANE_ACCESS 0x004 // mio2 E0104h
// mio2 E0106h
#define PEGC_REG_PLANE_ROP 0x008 // mio2 E0108h
#define PEGC_REG_DATASELECT 0x00A // mio2 E010Ah
#define PEGC_REG_MASK 0x00C // mio2 E010Ch
// mio2 E010Eh
#define PEGC_REG_LENGTH 0x010 // mio2 E0110h
#define PEGC_REG_SHIFT 0x012 // mio2 E0112h
#define PEGC_REG_PALETTE1 0x014 // mio2 E0114h
// mio2 E0116h
#define PEGC_REG_PALETTE2 0x018 // mio2 E0118h
#define PEGC_REG_PATTERN 0x020 // mio2 E0120h
typedef struct {
UINT8 enable; // PEGCプレーンモード使用可能
UINT8 lastdata[64]; // PEGCプレーンモード 最後にVRAMから読み取ったデータ
SINT32 lastdatalen; // PEGCプレーンモード 読み取り済みデータ長さ
UINT32 remain; // PEGCプレーンモード 転送データ残り?
} _PEGC, *PEGC;
#ifdef __cplusplus
extern "C" {
#endif
REG16 MEMCALL pegc_memvgaplane_rd16(UINT32 address);
void MEMCALL pegc_memvgaplane_wr16(UINT32 address, REG16 value);
UINT32 MEMCALL pegc_memvgaplane_rd32(UINT32 address);
void MEMCALL pegc_memvgaplane_wr32(UINT32 address, UINT32 value);
void pegc_reset(const NP2CFG *pConfig);
void pegc_bind(void);
#ifdef __cplusplus
}
#endif
#endif