2018年06月14日

SR画面周り(5)

  P6月間企画(その14)

  SRモードでの画面周りについて、の続きです。

  今回は、横320ドットのグラフィックモードについて、その3です。


○グラフィックモード320×200/320x204ドット

5)ビットマップモードで
・Y座標の設定を204以上にした場合はどうなる?
・X座標の設定を320以上にした場合はどうなる?

 実機でプログラムを組んでみて、調査しました。
 VRAMを全面0x00クリアした後に、XY座標を指定して描画し、VRAMのどこにセットされるかを見ています。

bitmap.zip


 結果をまとめると以下の通りです。

 X座標:
  下位10ビットのみ演算対象
  0x0000〜0x013F(=319)の時は、そのまま
  0x0140〜0x027F(=639)の時は、0x0140(=320)を引いた値で算出
  0x0280〜0x03FF の時は、演算結果が信用できない

  下位10ビットのみ演算対象のため、0x0400〜0x7FFFは上記0x0000〜0x03FFのイメージが出力されます。


 Y座標:
  下位9ビットのみ演算対象
  0x0000〜0x00CB(=203)の時は、そのまま
  0x00CC〜0x0197(=407) の時は、0x00CC(=204)を引いた値で算出
  0x0198〜0x01FF の時は、演算結果が信用できない

  下位9ビットのみ演算対象のため、0x0200〜0x7FFFは上記0x0000〜0x01FFのイメージが出力されます。


  通常は、範囲外を超えた設定を行わないと思います。しかし、この範囲外を超えた設定の時に、X座標は320、Y座標は204を引かれる処理は、プログラムで有効に使う事ができます。


  例えば、8x8のキャラクタ描画ルーチンを作る場合...

================================

ld hl,PATTERN ; パターン先頭
ld de,XADD ; X座標先頭
ld (.xpt+1),XADD

ld c,YADD ; Y座標先頭
ld b,8
.lp1:
push bc
ld a,c
out (0xCE),a

.xpt: ld de,0x0000
ldi
ldi
ldi
ldi
ldi
ldi
ldi
ldi

pop bc
inc c
djnz .lp1

================================

  こんな感じだと思います。

  通常の320x204で表示する場合は、X=0〜311、Y=0〜195 を指定すれば、画面全体にキャラクタを表示する事ができます。しかし、スクロールなどをしている場合は、X=311→X=0や、Y=203→Y=0のラインをまたぐようなキャラクタを描画する必要がありますよね?

  この場合に、上のようなプログラムで、X=0〜319、Y=0〜203を指定するだけで、場合分けをせずに描画が可能になります。これは、上のプログラム実行の途中に、X座標が320以上、Y座標が204以上になっても、X座標は320、Y座標は204を引かれる処理が行われているからです。


 注意)X座標が320以上、Y座標が204以上 は、エミュレータでは同じ動作をするかどうかはわかりません。



6)ビットマップモードで
・ポート0xC8のビット3でイネーブル/ディセーブルの切換だけど、ビット4のビットマップページ指定との関係は?
・メモリ割り当てと同時に使うとどうなる?
・そもそもビットマップモードとは?


 まず、VRAMとは、から。

 SRモードでのVRAMとは、0x0000〜0x7FFF(ページ0)、0x8000〜0xFFFF(ページ1)のアドレスを持っており、設定されているメモリの内容を画面に描くものです。

 ここで挙げている、0x0000〜0x7FFF、0x8000〜0xFFFF、というアドレスですが、SRの場合は直接CPUアドレスと繋がっていません。初代/mk2/66の場合は、直接CPUアドレスと繋がっているので、ややこしくないんですが...

 ビットマップモードの正体は、『ポート0xCE、0xCFの値(=Y座標)と、与えられたアドレス(=X座標)から、VRAMアドレスを算出する変換回路』です。

 直接アクセスモードの時は、この変換回路を使わずに、与えられたアドレス=VRAMアドレスになります。


 さらに、CPUから与えられるアドレスは、ポート0x60〜0x6Fのリード/ライト割り当て設定により変換されます。

 図に描くとこんな感じです。

180614_01_ビットマップモード.png


 CPUから与えられたアドレスは、まずリード/ライト割り当て設定で変換され、その後にビットマップモードで変換されます。直接アクセスモードの時は、リード/ライト割り当て設定のみで変換されます。


 また、ポート0xC8は、

 bit4:ビットマップページ指定(0:ページ0(0x0000〜0x7FFF)/1:ページ1(0x8000〜0xFFFF))
 bit3:ビットマップモード(0:イネーブル/1:ディセーブル(直接アクセスモード))

 なのですが、

 bit4=0、bit3=0 の時、ページ0(0x0000〜0x7FFF)にアクセスする時に、ビットマップモードで変換される
 bit4=1、bit3=0 の時、ページ1(0x8000〜0xFFFF)にアクセスする時に、ビットマップモードで変換される
 bit4=0、bit3=1 の時、直接アクセスモードなので、変換されない
 bit4=1、bit3=1 の時、直接アクセスモードなので、変換されない

 です。

 このビットマップモードの変換回路は1つしかないため、bit4を変更すると変換の対象も変更されます。

 bit4=0、bit3=0 を設定した後に、bit4=1、bit3=0 を設定すると、ページ0、ページ1ともビットマップモードになりそうなんですが、変換回路が一つしかないため、後に設定したページ1のみがビットマップモードになります。


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