2015年11月08日

パレット機能

  テクノウを作るに当たり機能ごとに書くのもいいんですが、画面周りが非常に大変そうなので...
  とりあえずI/Oポート順に攻めてみたいと思います。


  参考文献:Mr.PCテクニカルコレクション 秀和システムトレーディング


○ポート0x40:色番号16(HGRB=1111)のパレット色設定
○ポート0x41:色番号15(HGRB=1110)のパレット色設定
○ポート0x42:色番号14(HGRB=1101)のパレット色設定
○ポート0x43:色番号13(HGRB=1100)のパレット色設定

(ポート0x44〜0x4F:ポート0x40〜0x43のイメージ)


 ・SR以降のみに存在するI/Oポートです。
 ・SRモード(ポート0xC8:bit0=0)以外でも動作します。
 ・書き込みのみ。読み出しはできません(読み出すと0xFFになる)。

  書き込むデータは次の通り。

  bit7-4:don't care
  bit3:Hの反転
  bit2:Gの反転
  bit1:Rの反転
  bit0:Bの反転


◎解説
 いろいろとユーザには理解しがたい仕様のパレット設定です。

 なぜ、4色だけなのか?せめて8色なら88からの移植がラクなのに。
 なぜ、色番号13〜16なのか?せめて色番号1〜8なら、88で出せる色はそのまま使えるのに。

 と、88からの移植にすごく不向きなパレットです。

 設定する値は出したい色の反転を設定します。これもなぜ反転か不明ですが...

 例えば、色番号13に白(HGRB=1111)の設定する場合は、ポート0x43 に 0x00を出力します。


 また、SR-BASICのグラフィック全般に言える事ですが、SR-BASICではVSYNC割り込みを使って、常に画面設定をしています。

 そのため、SR-BASICのコマンドラインから、

 SCREEN 2,2,2:LINE (0,0)-(319,199),16,BF

 の後に

 OUT &H40,&H05

 としても、色番号16の白(HGRB=1111)が、赤(HGRB=1010)になりません。

 SR-BASICではなく、N66-BASIC(MODE5)で同じ事を実行した場合、ちゃんと所望の動作をします。
 (ただし、SCREEN 2,2,2 → SCREEN 3,2,2 とする)


 SR-BASICでは、ポート0x40〜0x43に出力した値をワークエリアに持っています。

 ポート0x40:0xED1F
 ポート0x41:0xED20
 ポート0x42:0xED21
 ポート0x43:0xED22

 これを使って、

 10 SCREEN 2,2,2:LINE (0,0)-(319,199),16,BF
 20 POKE &HED1F,&H05
 30 GOTO 30

 とすると、色番号16の白(HGRB=1111)が、赤(HGRB=1010)になります。



 このパレットが性能を発揮するのは、MODE5の320x200ドット表示の色を変える時ぐらいかも知れません。

posted by えすび at 12:25| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2014年06月03日

SRのグラフィックのバグ

  SRの簡易グラフィックモードでのハードウエアのバグの話です。
  バグは有名かどうか分かりませんが...


  SRでは、screen 1 で、width 80,25 をした場合に、簡易グラフィックが使えます。丁度、PC-8001の160x100のグラフィックと同じようになります。

  マニュアルにも記載があり、単純にグラフィックビットを1にするだけです。width 80,25 以外では、ガイコツや体のパーツみたいな、他のキャラクタが表示されますが、width 80,25 では、コードによって256パターンのグラフィックデータが表示されます。


  で、実際に使ってみると...バグがあります。

  一番右側(79文字目)のキャラクタの表示がおかしくなります。
  もうちょっと正確に言うと、160x100のドットで数えて、0.5ドット下にずれます(下にローテートしている)。



  試したプログラムはこれです。

グラフィック表示リスト.JPG



  実際の写真がこれ。一番右の所だけずれているのがわかると思います。

140603_01_160x100グラフィック.JPG



  さすがにエミュレータでは再現されていません(その必要もありませんが...)。
posted by えすび at 19:50| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2014年05月21日

SRのVRAMについて(4)

  SRのVRAM関連を調べていて(というか違うプログラムを作っていて)、どうもハードウエアのバグらしきものを見つけました。


  発生条件が確定していないんですが、今の所

  ・MODE6でグラフィックを2画面使う。
  ・ポート0xC9 で画面を頻繁に切り替える。

  画面を切り替えた時に、たまーに書き込んでいない部分のVRAMに、データが書き込まれます。

  どうも、ページ切り替えと、画面表示で、NGなタイミングがあるようなんですが、詳細を調査中です。
 

  MODE6 のテキスト2画面や、テキストとグラフィック、さらには、MODE1〜5に関して同じ問題が発生するかどうかは不明です。
 (多分、MODE1〜5は大丈夫だと思うんですが...)

posted by えすび at 20:37| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2014年05月12日

SRのVRAMについて(3)

  SRのVRAMのアクセス関連の調査中です。


  先日挙げた、


 ○グラフィックモードの場合


 ☆ポート0xC8 bit3=0 にすると、ポート0xCE、ポート0xCFで座標アクセスが出来る。逆に直接アクセスができない。
 ☆座標アクセスの際は、ページ番号によりポート0xC8 bit4を変更する。通常は、下位32K(ページ0)。
 ☆ポート0xC8 bit3=1 、bit4=0 にした場合、通常環境では暴走する。これは、BASICのワークエリアにアクセスができないため。

  ☆の1つ目の項目はこれで正解のようです。

  ただやっかいなのは、X座標0〜319、Y座標0〜203 の範囲なのですが、I/Oとしては両方とも16ビットあるため、範囲外にアクセスした時にどうなるかを調べる必要があります(調査中ですが、多少ヘンな動きをします)。

  また、上位32Kに座標アクセス(ビットマップアクセス)するためには、プログラムを二段階に組む必要があるので、まだ調べきれていません。



  ちなみに、画面を表示させながら、ディスクからロードするには、以下の方法で実現できます。

  SCREEN 2,2,2:POKE &HED1D,&HEE:BLOAD "ファイル名"


  0xED1D は、ポート0xC8の値を保存しているワークエリアで、VSYNC割り込みで読み出してポート0xC8に設定しています。

posted by えすび at 20:29| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2014年05月10日

SRのVRAMについて(2)

  SRのVRAMのアクセス関連がよく分からないので調べてみました。まだ途中ですが。


  Mr.PC Technical Collection を参考にしているのですが、間違っている所もあるようです。

  どうやったら、思っているモードの画面が表示されるのかがかなり分かり難いです。

  I/Oポートの0xC0〜0xCFをアクセスすればよさそうなのですが、いまいちすっきりしません。また、BASICからI/Oポートにアクセスしても、VSYNC割り込みの時に変更されるので、挙動が分かりにくくなっています。

  そこでプログラムを作ってみました。


srgraph.zip



  サブCPU以外の割り込みを禁止して、0xC1〜0xCF にアクセスできるようにしています。

  走らせると、0xC0〜0xCF に出力する値を入力すると、その値を出力します。
  任意のキー(スペースキーがベスト)を元に戻ります。

  事前に、0x0000〜0x7FFFにグラフィックデータをロードさせると、挙動が分かりやすいです。



Mr.PC Technical Collection でのI/Oポートの説明は以下の通りです。

 ポート0xC1
  bit7-4:1固定
  bit3:1=横320ドット。0=横640ドット。
  bit2:1=キャラクタモード。0=グラフィックモード。
  bit1:1=40文字。0=80文字。
  bit0:1=縦200ライン。0=縦204ライン。

 ポート0xC8
  bit7-5:1固定
  bit4:ビットマップのページ指定。1=上位32K。0=下位32K。
  bit3:1=ビットマップDisable。0=ビットマップEnable。
  bit2:1=20行。0=25行。
  bit1:1=バスリクエストOFF。0=バスリクエストON。
  bit0:1=旧BASIC。0=SR-BASIC

 ポート0xC9
  bit7-4:0固定
  bit3-0:VRAMアドレス指定(ページ1〜16)



  これを動作ごとにまとめた結果が以下の通りです。


 ○キャラクタモードの場合

  ポート0xC1 bit2=1にする。
  画面サイズは、ポート0xC1 bit1 と、ポート0xC8 bit2 で決定する。
  表示ページは、ポート0xC9 で決定する。

  ポート0xC1 bit3、bit0 は、グラフィックモード用の設定のため、無関係になる。

  ポート0xC8 bit0=0 に設定しておく必要あり(SR-BASICのため)
  ポート0xC8 bit3=1 に設定しておく。


 ○グラフィックモードの場合

  ポート0xC1 bit2=0にする。
  画面サイズは、ポート0xC1 bit3 bit0 で決定する。
  表示ページは、ポート0xC9 で決定する。ただし、bit2-0 は無視される。bit3=ページ番号となる。

  ポート0xC1 bit1 と、ポート0xC8 bit2 は、キャラクタモード用の設定のため、無関係になる。

  ポート0xC8 bit0=0 に設定しておく必要あり(SR-BASICのため)


 ☆ポート0xC8 bit3=0 にすると、ポート0xCE、ポート0xCFで座標アクセスが出来る。逆に直接アクセスができない。
 ☆座標アクセスの際は、ページ番号によりポート0xC8 bit4を変更する。通常は、下位32K(ページ0)。
 ☆ポート0xC8 bit3=1 、bit4=0 にした場合、通常環境では暴走する。これは、BASICのワークエリアにアクセスができないため。

  最後の☆の行に関しては、まだ調査中です。

posted by えすび at 20:44| Comment(9) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2014年05月07日

SRのVRAMについて

  SRのVRAMは、構成が結構ヘンなんですが...


  気になるツイッターの発言を見つけました。

 『SRのグラフィックをBSAVEしたデータをロードする際、SCREENを表示させずに裏側でBLOADさせるとちゃんと画面が表示されるが、SCREENを表示させた状態でBLOADさせると画面がちゃんと表示されない』

  実際にやってみました。


  SR上でグラフィックデータを作るのが面倒だったので、P6VW上で、以下の手順でデータを作りました。

 1)適当なソフトを走らせて、0x0000〜0x7FFFをgetbinコマンドで一度ファイルに落とす。
 2)フォーマット済みの.d88を挿入して、モード6で立ち上げて、setbinコマンドでVRAMにデータを戻す。
 3)BSAVE "ファイル名",0,&H8000 で、ディスクにセーブする。


  上記の.d88を使って、P6VW上で

 ・SCREEN 2,2,2:BLOAD "ファイル名"

  をすると、確かに変なロード状態になります。


  で、問題はここからで、

 ○P6VW
 ○P6V
 ○iP6plus
 ○実機

  で、この変なロード状態に差異があります。

  実機では、最下行だけにロードデータが表示されるのですが、エミュレータでは、X座標が0〜255の分だけは表示されてしまいます。


  何となく予想はついているんですが、まだちゃんと調査できていません。


  また、上記の.d88ファイルを使って、

 ・SCREEN 2,2,2 を実行した後、SCREEN 1 で、BLOAD "ファイル名"

  を実行した場合、

 ○P6VW
 ○iP6plus

  では、正常な画像が表示されるんですが、

 ○P6V
 ○実機

  では、正常な画像が表示されません。X座標が256〜319のデータがナゼか1行置きに表示されます。

  多分、P6VWで作成したデータ自体がおかしいんだと思いますが、これも調査中です。


posted by えすび at 20:00| Comment(3) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2013年04月03日

CRTCのバスリクエストOFF(3)

  前言撤回です。


>> ・CRTKILL の解除は、水平同期(横の行)単位で行われている。
>> ・CRTKILL の最中に表示されるデータは、画面右下(データとアトリビュートの両方)が表示される。


  画面の右下のデータが表示されるのではなく、最後に描画したデータを表示するようです。

  ↓サンプルプログラムです。

crtkill.zip


  先のプログラムとほとんど変わりませんが、WAIT値を2つ設定できるようにしました。
  垂直同期からどれくらい待つか(WAIT1)と、その後どれくらいCRTKILLするか(WAIT2)です。


  画面の縞模様(もしくは真っ黒)の部分が、CRTKILLしている期間になります。

  WAIT1 に、0x0118〜0x011Eを入れると右下のデータが繰り返されるのではなく、水色の線が表示されます。
  (WAIT2は、CRTKILLの幅なので、0x0200ぐらいでいいでしょう)

  WAIT1 に、0x0110〜0x01C0 ぐらいの値なら、画面右下のデータが表示され、0x120より大きいと、真っ黒な横帯になります。


  何となく使えそうな使えなさそうな機能です...

posted by えすび at 22:37| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2013年04月02日

CRTCのバスリクエストOFF(2)

  mk2、66で、バスリクエストOFF(OUT &H93,2)をした場合の挙動を調べて面白い事が分かりました。


  ↓がCRTC周りの回路図です(以前にアップしたものから一部を修正しています)。

pc6001mk2_crtcnt


  CRTKILLの信号を、一度H-SYNCで叩いてから、LSIに入力しています。

  これはもしかして1行単位でCRTKILL(バスリクエストOFF)が出来るのでは?
  という事で調べてみました。

  ↓が作成したプログラムです。

crtkill.zip


  Mode5,Page3 で動かして下さい。

  RUN すると、WAIT値を聞いてくるので、とりあえず 200 を入力してみて下さい。
  上の方に縞模様が出ると思います(時間が経つと変化します)。
  スペースキーを押すと、ループから抜けます。

  プログラムの内容は、以下の通りです。

 1)垂直同期が来るまで待つ
 2)CRTKILL (バスリクエストOFF)にする
 3)一定時間待つ
 4)CRTKILL を解除する(バスリクエストONにする)
 5)1)に戻る


  です。5)で戻る前に、画面左上と右下に適当な値を書き込んでいます。


  実行してもらうとわかりますが、CRTKILL (バスリクエストOFF)は以下のように動作しているようです。

 ・CRTKILL の解除は、水平同期(横の行)単位で行われている。
 ・CRTKILL の最中に表示されるデータは、画面右下(データとアトリビュートの両方)が表示される。



  ただ、CRTKILL の設定は、水平同期(横の行)単位で行われているかどうか不明です。

  今回のプログラムでは、1フレーム間に、
    CRTKILL設定→CRTKILL解除
  ですが、これを1フレーム間に、
    CRTKILL設定→CRTKILL解除→CRTKILL設定→CRTKILL解除
  とやっても、縞模様が2つ出来るような期待通りの動作をしてくれません。


  やっぱり動きがナゾです...

posted by えすび at 18:36| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2013年01月16日

色ずれの話(1)

  ふと思いついたので、色ずれを制御する回路を組んでみました。


  以下が実施した結果です。
  実行はmk2上で行い、電源などは切らずに色を変えています。


色ずれ緑・桃

  mk2では、普通の色ずれです。


色ずれ桃・緑

  色が入れ替わっています。電源を切ると入れ替わる事はありますが、通常は入れ替わりません。


色ずれ青・赤

  初代機での色ずれの色です。


色ずれ赤・青

  上の色の入れ替わり。


色ずれ紫・黄緑

  紫と黄緑の組み合わせ。全体的に青っぽい印象です。


色ずれ黄緑・紫

  上の色の入れ替わり。


色ずれ赤紫・緑

  赤紫と緑の組み合わせ。この緑と、通常の色ずれの緑は、違う色です。


色ずれ緑・赤紫

  上の色の入れ替わり。



  原理を詳細に説明すると大変なので、すごく端折ると、『カラーバースト信号のみ、タイミングをずらす』事をしています。

  回路は簡単で、mk2のRFモジュールに入力されている、3.58MHzのクロックをずらしているだけです。



CLOCKSFT回路

  これが回路図です。74LS00 で組んでいるのは、単なるセレクタです。
  元の3.58MHz、14MHz は、mk2本体から取って、ずらしたクロックをRFモジュールに入力しています。

  スイッチの組み合わせで、3.58MHzを、14MHzの半分の単位でずらしています(8通りの組み合わせになる)。


色ずれ変換回路実装1

  実際に実装した所です。緑の線が、mk2のIC47につながっています(見づらいですが)。


色ずれ変換回路実装2

  RFモジュールに戻している所です。
  RFモジュールへのケーブルを切ったり、パターンカットをするのがイヤだったので、入力の初段のコイル(L1)を外して、そこに入力しています。



  実は、色ずれ以外の、普通の色にも影響がありそうなんですが、あまり確認をしていません。
  色ずれした色が結構キレイだったので(^^;

posted by えすび at 21:29| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2013年01月15日

CRTCのバスリクエストOFF(1)

  mk2、66で、バスリクエストOFF(OUT &H93,2)をした場合の挙動が不思議です。

  MODE5、PAGE4にして、起動直後(SCREEN1)で、OUT &H93,2 をすると砂嵐になります。

  OUT &H93,3 で元に戻した後、
  SCREEN 3,2,2:OUT &H93,2
  とすると、画面が真っ黒になったまま、砂嵐にはなりません。

  その後、OUT &H93,3 で元に戻した後、同じように
  SCREEN 3,2,2:OUT &H93,2
  とすると、今度は砂嵐になります(たまに真っ黒になる)。

  上のコマンドの代わりに、
  SCREEN 4,2,2:SCREEN 3,2,2:OUT &H93,2
  とすると、100%、真っ黒です。


  SCREEN 3,2,2:OUT &H93,2
  だけだと、砂嵐になったり、真っ黒になったりと、結果が変わります。


  この辺りのタイミングは、CRTC のLSI に CRT-KILL のコマンドを入力する時に、H-SYNC の立ち上がりで叩いているので、H-SYNC が関係しているようなんですが、よくわかりません(以前にアップした回路図は、一部間違えていました)。


  画面が真っ黒ではなく縞模様になる事もあるので、どこかのタイミングでデータをラッチしているようなんですが、どーもよくわかりません...


  もうちょっと解析をしてみて、FPGA版にも反映させたいと思います(今のバージョンは中途半端)。


posted by えすび at 21:23| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年12月02日

画面描画期間検出(7)

  昨日アップした画面描画期間の検出プログラムは、やはり間違っていたようです。

  改定版をアップします。

vsync2_2.zip

  拡張RAMが必要で、ページ4です。
  前と同じですが、画面切り換えを使っている関係で、mk2、66では動作しません。



  方法ですが、基本は同じです。

・画面描画期間の検出の方法(基本)

  画面描画期間の時だけ止まっているCPU で、その止まっている期間を検出するためには、CPU の外部に基準の時計が必要になります。
  SUB-CPU がつながっている8255 のポートを使用します。

  特定ポートにデータを書き込むと、4MHz で60〜80クロックぐらいかかる処理があります。


  これを使い、画面描画期間を判定します。

  データ書き込み
  ↓
  4MHz で50クロックぐらい待つ
  ↓
  処理が完了しているかを判断する


  画面描画期間以外:処理が完了しない。
  画面描画期間:CPU が途中で止まっているため、実際には50クロック以上の時間が経っており、処理が完了する。

  で判断します。


・画面描画期間の検出の方法

  上記の基本の検出を4度行います。その際、一定期間(具体的には155クロック)空けます。
  こうすると、画面描画をしている時は、4度の検出のどこかで検出できるようになります。

  ただし、検出には大体8走査線分(描画期間中)、3走査線分(描画期間中)の時間がかかります。


  初代P6では、1走査線は 910クロック@14M(253クロック@4M)分の時間で、CPU が動作できる期間はその内の、296クロック@14M(83クロック@4M)ぐらいです。
  また、mk2、66では、1走査線は 912クロック@14M(255クロック@4M)分の時間で、CPU が動作できる期間はその内の、304クロック@14M(85クロック@4M)です。

  この走査線とCPUが動作できる/動作できない期間はほぼ一定間隔なので、検出期間をいい感じにすると、4度の検出の間のどこかで引っ掛けることが出来ます。


vsyncdet.xls


  ↑が説明の図です。

  ピンクの長方形が、検出方法の基本で書いている、サブCPU の処理完了待ちです。ピンクの最後で処理が完了しているかどうかを判断します。
  ピンクの最後が水色になっているのは、そのタイミングで画面描画期間(CPUが止まった期間)を検出できることを示します。


  サブCPUにアクセスする間隔をもっと短くすればよさそうなんですが、短くすると応答の時間が極端に長くなったり短くなったりと、変になります。
  なので、実測から今の155クロック間隔にしています。


 サンプルプログラムでは描画期間判断ルーチンを2度呼んでいますが、これは

 1)描画期間が開始されるまで待つ。その後に
 2)描画期間が終了するまで待つ。

 として、描画期間が終了した直後を探しています。

 2)描画期間が終了するまで待つ。だけでよさそうなんですが、これだと描画期間直後ではなく、中間の時も検出される場合があるからです。

 マウスのプログラムを作った時にハマりました(^^;



  ちなみに、PC-6001F の方でも、サブCPU からの応答値を合わせましたので、同じように動作すると思います。


posted by えすび at 23:26| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年12月01日

画面描画期間検出(6)について

  プログラムを見て、書いている事が矛盾しているのを発見。

  「2回検出」と書いていますが、「2回検出」のサブルーチンを2回コールしていました。


  だいぶ前に作ったので忘れてますが...1回コールに直すと全然ダメなので、とりあえず動いているバージョンが正しいという事で...



  「2回検出×2回コール」で、ちゃんと動いているようなんですが、もう一度見直す必要がありそうです。




posted by えすび at 16:33| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

画面描画期間検出(6)

  以前に作成した画面描画期間の検出プログラムを改定しました。

vsync2_2.zip


  拡張RAMが必要で、ページ4です。

  前と同じですが、画面切り換えを使っている関係で、mk2、66では動作しません。


  方法ですが、基本は同じです。

・画面描画期間の検出の方法(基本)

 画面描画期間の時だけ止まっているCPU で、その止まっている期間を検出するためには、CPU の外部に基準の時計が必要になります。
 SUB-CPU がつながっている8255 のポートを使用します。

 特定ポートにデータを書き込むと、4MHz で60〜80クロックぐらいかかる処理があります。


 これを使い、画面描画期間を判定します。

 データ書き込み
 ↓
 4MHz で45クロックぐらい待つ
 ↓
 処理が完了しているかを判断する


 画面描画期間以外:処理が完了しない。
 画面描画期間:CPU が途中で止まっているため、実際には45クロック以上の時間が経っており、処理が完了する。

 で判断します。


・画面描画期間の検出の方法(改定)

 上記の基本の検出を2度行います。その際、一定期間(具体的には96クロック)空けます。
 こうすると、画面描画をしている時は、1度目か2度目の検出で検出できるようになります。

 ただし、検出には3走査線分の時間がかかります。

 初代P6では、1走査線は 910クロック@14M(253クロック@4M)分の時間で、CPU が動作できる期間はその内の、296クロック@14M(83クロック@4M)ぐらいです。
 また、mk2、66では、1走査線は 912クロック@14M(255クロック@4M)分の時間で、CPU が動作できる期間はその内の、304クロック@14M(85クロック@4M)です。

 この走査線とCPUが動作できる/動作できない期間はほぼ一定間隔なので、検出期間をいい具合にすると、1度目の検出では引っ掛からなかったものを2度目の検出で引っ掛けられます。

 図を描いて、タイミングを計算しないと、すごく分かりにくいですが...



 ロジアナで、プログラムを動作中のものを見ましたが、多分ちゃんと動いているんじゃなかと思います。







posted by えすび at 14:58| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年08月08日

画面描画期間検出(5)

 画面描画期間検出(1) で使っていた手法ですが、8255 のモード2のレスポンス時間(正確には、sub-CPU の割り込みから読み出しまでのレスポンス時間)を使っていました。

 ただ、これだとちょっと短すぎるようで、画面描画期間を検出し損なうことがあります。


 他に使えそうなのが、sub-CPU のゲームキー検索です。
 これは、sub-CPU にコマンド(0x06)を出力して、sub-CPU からのデータ(0x16+キーデータ)が返ってくるレスポンス時間を計るものです。


 で、調べてみましたが...

 レスポンス時間が、HSYNC で数えて15〜40行分ぐらいと、えらく幅がありました。
 HSYNC 1行分が、912clk@14Mですので、大体 977μs 〜 2605μs と余り使え無そうです。

 sub-CPU のプログラムを読んだわけではないので何とも言えないですが、キーマトリックスにアクセスするタイミングが一定になっているために、レスポンス時間が一定にならないんじゃないかと思います。


posted by えすび at 17:10| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

画面描画期間検出(4)

  先に書いた追加ハードウエアを実際に組んでみました。
  その4の回路では問題がありましたので修正しています。


・その4改

  MREQ がネゲート(つまり CPU から読み書きされない)、CAS がアサートされた時にそのアドレスをラッチする。
  この条件の時は、画面描画範囲からデータを読み出しているタイミングなので、どのアドレスにアクセスしているかが読み出せます。

  実際の回路は、それ以外にラッチしたアドレスをクリアする機能が必要になります。


  組んでみた回路がこれです。

VSYNC検出回路例改

  I/O ポートは、0x40(アドレス下位)、0x41(アドレス上位)で、0x41 アクセス時は同時にクリアします。
  手抜き仕様なので、クリアというよりアクセスした時のアドレスが入ります。

  MREQ を1クロック引き伸ばしているのは、MREQ に対して CAS がちょっと遅れて出力されるための処置です。



  動かしてみたテストプログラムがこれです。

vsynccir.zip



  実際に動かした所です。





  うちの P6 の調子があまりよくないせいか色がヘンになったりしますが、水平2分割が出来ています。


posted by えすび at 14:59| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年08月05日

画面描画期間検出(3)

 Hashiさんトコの掲示板に書いたものの追加、変更です。

 画面描画期間ですが、拡張コネクタに外付け回路を使う事により、確実に検出が可能になると思います。
 拡張コネクタには、アドレスバス、ライト、リードなどの信号が出ているので、これらを使用します。


・その1
 通常のCPUからアクセス時は、4MHz。
 VDG からのアクセス時は、14MHz。

 アドレスバスの変化タイミングを見る方法です。
 タイミング的にちょっと厳しいかも。


・その2
 VDG からのアクセスは、アドレスが決まった変化をします。
 (スクリーンモードによりますが)
 その変化のパターンを調べて、学習する回路を作ります。

 例えば、スクリーン3ページ2の場合、

 E000 E200 E001 E201 E002 E202 ・・・ となるので、このパターンを
 探して、1フレーム後にも同じパターンが来るかを見るような回路です。


・その3
 初代P6 のみの方法です(mk2以降は不可)。

 通常のCPUからのアクセス時は、RAS をアサート、CAS をアサート、ですが、
 VDG からのアクセスは、RAS をアサート、CAS をアサート、CAS をアサートと
 RAS1回に対して、CASを2回出力します。

 このパターンを見つけてフレームレベルで周期監視するのが、割と簡単そうな回路です。


・その4
 これも初代P6 のみの方法(mk2以降は、不可)で、多分回路が一番簡単で、使いやすそう。

 M1 がネゲート、CAS がアサートされた時、つまりCPU のM1サイクル以外でRAMからリードされた時のアドレスをラッチする。
 これを適当なI/Oポートに割り当てて、CPUから読み出すというものです。

 CPU がメモリからの読み出しを行った後で、画面描画期間になれば、VRAM のアドレスが読める事になります。
 また、VRAM のアドレスで、何行目を描画しているかが判別できます。

 判別前にメモリからの読み出しを数命令分止める必要がありますが、判別の長さを調整できたり、何行目かが判別できるというメリットがあります。



 その4をディスクリートで組むと、こんな感じでしょうか。

VSYNC検出回路例


 M1 の信号を1クロック遅らせているのは、M1の変化点とCASの変化点が同じために、ハザードが誤動作する可能性があるためです。

 実際に試していないので、動くかどうかはわかりません...


posted by えすび at 21:15| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年08月04日

画面描画期間検出(2)

 画面描画期間検出(1) でアップしたプログラムですが、mk2以降では期待通りに分割されません。

 これは、初代機とmk2以降で、表示画面の取り込みが違うためのようです。

 初代機:ポート0xB0 の値で、逐次変更される →画面描画途中でも表示ページが変更される
 mk2以降:1画面描画する直前で、ポート0xB0 の値を記憶する →画面描画途中では、表示ページが変更されない



 ちなみに、画面描画期間検出(1) でアップしたプログラムの ウエイト時間を変更すると、違う画面になります。

 vsync.p6 の 2120行の最後の 01,00,03 を 01,80,05 にすると、SCREEN3 とSCREEN4 の重ね合わせになります(かなりちらつきますが)。


 実際の動画がこちら。




 ビデオ出力したものですが、よくみるとSCREEN3 が1行置きに表示されています。

 これは、SCREEN3 描画 → SCREEN4 描画 → SCREEN3 描画、と1フレーム毎に交互に描画されているためのようです。


 画面がちらつくのは、画面描画期間検出のタイミングが多少ずれたり、検出ルーチンを通らなかったりするためで、mk2以降の機能にあるAY-3-8910のポ

ート経由でVSYNC を検出すると、ちらつきがなくなります。


 実際の動画がこちら。




 プログラムはこちらです。

vsyncmk2.zip


posted by えすび at 14:49| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

画面描画期間検出(1)

 まず、以下の画像をご覧下さい。DSi で撮ってるので、画像が悪いですが...




 これは、PC-6001 初代機で動かしたものです。外部に余計はハードウエアは付けていません(RAMは32Kにしていますが)。


 境界がちらちらと動くのがイマイチなんですが、一応画面の上半分はSCREEN4、下半分はSCREEN3 になっています。

 これは、ソフトウエアで画面描画期間を検出して、そこから一定時間後に画面の切り替えを行ってます。
 (事前にページ3とページ4を、SCREEN3 とSCREEN 4 に設定しています)



 プログラムがこれです。

vsync.zip



 ・画面描画期間の検出の方法

 画面描画期間の時だけ止まっているCPU で、その止まっている期間を検出するためには、CPU の外部に基準の時計が必要になります。
 今回は、SUB-CPU がつながっている8255 のポートを使用しました(詳細は後述)。

 特定ポートにデータを書き込むと、4MHz で64クロックぐらいかかる処理があります。


 これを使い、画面描画期間を判定します。

 データ書き込み
 ↓
 4MHz で40クロックぐらい待つ
 ↓
 処理が完了しているかを判断する


 画面描画期間以外:処理が完了しない。
 画面描画期間:CPU が途中で止まっているため、実際には40クロック以上の時間が経っており、処理が完了する。

 で判断します。


 ・8255のポートの話

 かなりハード寄りの話です。

 SUB-CPU とメインCPU との通信のために、8255 のモード2を使っている、という話は周知だと思います。
 このモード2ですがもっと細かく見ると、以下のようになります(SUB-CPU に出力時)。

 OUT 0x93,0x08 :INTE2 をリセットして、リード側のポートを無効にする(→ライト側のポートのみ有効になる)。
 ↓
 IN (0x92)  :bit3 とbit7 が 1 になるまで待つ(8255が受信可能になるまで待つ)
 ↓
 OUT 0x93,0x09 :INTE2 をセットする(後のためにINTE2を戻しておく?)。
 ↓
 OUT 0x90,DATA :SUB-CPU へ出力するデータを書き込む。


 最後のデータを出力すると、8255 の port-C の bit7(OBF)が、H→L になります。この信号が、SUB-CPU の割り込み信号になっています。
 ↓
 SUB-CPU は、割り込みが発生すると、データを読み出すためにリードイネーブルをLにします。この信号が、8255 の port-C の bit6 (ACK) になっています。
 ↓
 8255 は、8255 の port-C の bit6 (ACK) がLになると、読み出しが完了したと判断して、port-C の bit7(OBF)をL→Hとして、処理が終了します。



 一連の動きを実機のPC-6601 で測定したものがこれになります。動きとしては、初代機PC-6001 でも同じです。

SUBCPUアクセス


 画面描画期間はちゃんと検出出来ているようですが、毎フレーム検出できるというわけではありません。
 それは、(当然ですが)画面描画期間中に検出ルーチンを通らないと検出できないため、プログラムのループが長い時には、検出できないことがあるようです。






posted by えすび at 14:06| Comment(6) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年06月04日

スクリーン3と4の混在のバグ(2)

 スクリーン3と4の混在のバグに関して、原因がわかりました。

 ゆみたろさんにもコメントをもらっていましたが、原因はVDG周辺の回路ではなくVDG本体でした。


 これは、MC6847 のブロック図の一部です(MC6847のマニュアルより。16ページ)


MC6847のブロック図


 A/G、GM2-0 にはFFが入っておらず、それ以外の信号にはFFが入っています。

 この信号は、アトリビュートを読み出した結果がそのまま入力されるため、A/G、GM2-0 と他の信号は1クロックずれて変化する事になります。
 これにより、アトリビュートが1つずれているようです。

 CSSには FFが3つ入っていますが、これで他の信号(A/S、INT/EXT、INV)と段数が合っているようです。


 この結果、アトリビュートのアドレスがずれてしまうのは、GM2-0 のみです。
 (A/G は、実際には混在して使う事が出来ないので、考慮しなくてもいいでしょう)


 mk2以降は、このずれを回路に入れていないようなので、アトリビュートがずれずに表示されます。



posted by えすび at 18:18| Comment(2) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年03月27日

実機との比較の結果


  色が明るすぎるのは、とりあえずMORIYAさんトコの写真の色に合わせるようにしました。
  http://p6ers.net/mm/pc-6001/dev/p6color_chk/

  写真の色から、RGBを抽出するツールを使って、データを作成しました。



  ボーダーの縞模様(ジャン狂の方)は、原因は判りましたが、修正が大変です...

  SCREEN1とSCREEN4のアトリビュートの混在をどうするか、という問題になります。



  AX-7 デモの背景の縞模様に関しても、原因はわかりました。

  あの縞模様は、単純に色を連続で変えているだけのようです。

  で、画面を書き換えるタイミングと、画面を表示するタイミングが、微妙にずれた時に、あのようなキレイな縞模様が出るようです。


  FPGA版では、VGA出力のタイミングが関わってくるので、映り方が変わっているようです。


  また、エミュレータでは、走査線1ラインずつ書いているわけではないため、画面全体の色が変わるんだと思います、多分。


posted by えすび at 21:39| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年03月26日

PC6001の色について

 今更ながらに気付いたんですが...

 PC-6001 の画面の色(例えば起動直後の緑色)が全然違う!!!


 全体的に何だか明るすぎますよね?


 色の変換の時に間違えたのかも。これも修正する方向で検討します。


posted by えすび at 19:02| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

P6のVDGのボーダーの色

 拡張RAM が使えるようになったので、気になっていたソフト(ジャン狂)をテスト。

 このソフトでは、左右のボーダーに縞模様が入ります。

 これは、アトリビュートを操作しているだけです。
(MORIYAさんトコに詳しく書いています → http://p6ers.net/mm/pc-6001/dev/p6color_chk/mode3_attr.html


 FPGA版の実行結果がこちら。

ジャン狂FPGA右上

ジャン狂FPGA左上



 右端のボーダーのすぐ左の1バイト分が色が変わるのは分かるんですが、左端のボーダーのすぐ右の1バイトも色が変わっています。しかもちらちらと点いたり消えたりしています。


 で、実機。

ジャン狂実機右上

ジャン狂実機左上



 FPGA版と明らかに違います(左右の緑色が違うのは、カメラの補正が入っちゃったためです)。

 ・上下のボーダーの色が緑色
 ・左右のボーダー(縞模様)の色が緑色
 ・右端のボーダーのすぐ左の1バイトは、ベタ緑。
 ・左端のボーダーのすぐ右の1バイトはちらちらしない。


 うーん、これも修正する方向で考えるとしましょう。

posted by えすび at 19:00| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2012年01月15日

mk2のバスリクエストについて

  mk2 になってから、加速モードでのCMT のロードを待たせる時間が長くなっています。


  具体的には、1バイトのデータを読み出すのに、

  P6 :3.93ms
  mk2:2.62ms

  と、1.5倍の時間待たせています。


  mk2 のBASIC のプログラムの方がドンくさいんだと思っていたら、どうもそうではなかったようです。


  mk2 のCRTC のBUSRQ を調べた結果、MODE2 とMODE5 でかなり違います。

  CRTC は水平ライン262本分で1周しますが、その内、MODE2 では192回BUSRQがLになり、MODE5 では200回BUSRQがLになります。
  これは縦192ドット/200ドットに相当する数字です(当然ですが)。

  また、その1ライン中(456クロック)にLになる区間が、MODE2 では304クロック、MODE5 では368クロックです。
  これは、横の256ドット/320ドットに少しだけ大きい数字です(Z80がすぐに止まらないので余裕を持たせています)。


  で、BUSRQ がLの期間はCPUが止まっているとして計算すると...

  MODE2:48.85%
  MODE5:61.60%

  の期間、BUSRQ で止まっている計算になります。


  mk2 止まりすぎですね(−−;


  で、CMT のロードの話ですが、CPUが速く動けば待たせる時間が少なく済むので、ロード時間も短くなります。

  CMT ロードの時には、CRTKILL をすれば取りあえず速くなります。


  が、画面を全く消さなくても間引けばいいのでした。


  通常の6001だと間引いても画面が乱れますが、FPGA版はVGAモニタへの画面表示のために、2P-RAMで乗せ換えをしているために間引いても問題ないんですね。


  修正が完了したら、またアップします。

posted by えすび at 21:28| Comment(2) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2011年12月30日

mk2設計(3)

  PC-6001 のVDG である MC6847 と、mk2 のCRTコントローラですが、未サポートの画面以外に微妙に違う所があります。

  一つはセミグラフィックの表示の仕方で、mk2 ではキャラクタROMからデータを読み出しています(つまりセミグラフィック表示ではなく、グラフィックのキャラクタを表示させている)。

  もう一つは、水平同期のクロック数で、PC-6001 は 14.31818MHz で 910クロックに対して、mk2 は 912クロックです。



  他にも違いがありそうなので、FPGA化の際は、両方のコントローラを載せる事にします。

  幸い、回路規模はそんなに大きくありません(カウンタの固まりのイメージです)。



posted by えすび at 19:10| Comment(6) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする

2011年12月22日

VSYNC読み出し

  AY-3-8910 のポートから、VSYNC、HSYNC が読み出せる事は、前に書いていますが、実際にテストプログラムを組んで見ました。

VSYNC読み出しテスト


  ページは2ページ以上を指定して、mk2以降の実機で実行してみて下さい。
  BASICには戻らないので、リセットで終了して下さい。


  プログラムの内容は、単純にSCREEN3で色を次々に変えているだけです。

  実行すると、画面がちらつきますが、その境界線がほぼ一定になります。
  VSYNCを検出しているため、同じタイミングで書き込みをしているため、境界線が一定になります。


  180行〜200行の書き込み値を&H00 にすると、VSYNCを無視します。この場合、同じように画面がちらつきますが、境界線が一定になりません。


posted by えすび at 21:54| Comment(0) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする