ORANGE pico のTFT液晶モードの挙動をもう少し調べてみた。
cpoke によるパターンの設定は効くか?
ORANGE pico では、cpoke
という、キャラクターコードに対応するパターンを設定するコマンドがある。
これまで、cpoke
について、ビデオ出力モードでは
- テキスト画面に表示するキャラクターのパターンを変更できる
- 設定は、既に画面に表示されているキャラクターにも遡って適用される
-
gprint
コマンドで使用するフォントはなぜか変更されない
ということがわかっている。
以下の画像は、「hello world」を出力させた後、cpoke
コマンドにより空白 (&H20
) のパターンを音符 (9
) に変更し、再び「hello world」を出力された様子である。
テキスト画面への出力では空白が音符に置き換わっているが、gprint
コマンドによるグラフィック画面への出力では空白が空白のまま出力されている。
同様の実験をTFT液晶モード (spitft 1
) で行うと、以下の画面になった。
以下すべてにおいて、cpoke
による設定は反映されていないことがわかる。
-
cpoke
の実行前に表示されていた文字 -
cpoke
の実行後にUART入力を反映して出力された文字 -
cpoke
の実行後にprint
コマンドにより出力された文字 -
cpoke
の実行後にgprint
コマンドにより出力された文字
さて、ビデオ出力モードでは、cpoke
によるキャラクターパターンの設定は cpeek
により読み込まれるキャラクターパターンにも影響する。
TFT液晶モードでも試してみると、ここは同様に反映されるようである。
&H80台、&H90台のフォントは?
以前の記事で、テキスト画面とグラフィック画面で &H80 台などのフォントが違うことを紹介した。
そこで、これらのフォントがTFT液晶モードではどうなっているかを確認する。
たとえば、以下のプログラムを実行し、&H80 台および &H90 台の文字を出力してみる。
10 for i=&H80 to &H90 step &H10
20 for j=&H0 to &HF
30 print chr$(i+j);
40 next
50 print ""
60 next
結果は、ビデオ出力モード・TFT液晶モードともに罫線の文字が出力された。
さらに、以前の記事で紹介した以下のプログラムを実行し、gprint
でどう出力されるかも見てみる。
10 cls:white=rgb(255,255,255)
20 for y=0 to 15
30 for x=0 to 15
40 c$=chr$(y*16+x)
50 locate x+2,y+4:print c$;
60 gprint 8*(x+22),8*(y+4),c$,white
70 next
80 next
90 if inkey()==0 then goto 90
結果は、ビデオ出力モードと同様に gprint
では print
とは異なる文字が出力されたり、8×8の領域からはみ出して描画されたりする現象を観測できた。
vmove による VRAM とのやり取りは?
ORANGE pico では、vmove
コマンドにより、メモリー配列の内容をテキストVRAMにコピーしたり、テキストVRAMの内容をメモリー配列にコピーしたりできる。
以前の記事で紹介した以下のプログラムで、TFT液晶モードにおける vmove
コマンドでのテキストVRAMへのコピーの挙動を見てみる。
10 cpoke
20 mset 0, 0, 1000
30 lx=12:ly=4
40 for i=0 to 15
50 c=asc(format$("%X", i))
60 mpoke 40*(ly-2)+lx+i, c
70 mpoke 40*(ly+i)+lx-2, c
80 next
90 for y=0 to 15
100 for x=0 to 15
110 mpoke 40*(ly+y)+lx+x,16*y+x
120 next
130 next
140 vmove 0, 1
150 locate 0, ly+16
160 if inkey()==0 then goto 160
以下が、プログラムの実行直前の様子である。
プログラムを実行し、さらにキーを押して終了させた。
130行目の位置に「OK」が出ている。
にもかかわらず、VRAMへの書き込みは反映されず、入力したプログラムがそのまま表示されている。
カーソルを画面の一番下まで移動させ、さらにCRを送信してスクロールさせると、VRAMに書き込んだ内容が反映された。
TFT液晶の縦モード (spitft 4
) でも試してみた。
実行後、カーソルを動かしてみると「ネノハヒフヘホマ」が現れ、VRAMへの書き込みは行われている様子だった。
しかし、TFT液晶の横モードとは異なり、スクロールさせても書き込んだはずの内容は反映されなかった。
ここで、公式のコマンド一覧の vmove
の説明には、以下のように書かれている。
テキストVRAMサイズは1000バイトありますので、アドレスの指定に注意してください
TFT液晶モードでは、画面の文字の枠は40×30=1200あり、1000を超える。
超えた分がどうなるか気になるので、以下のプログラムで実験をしてみた。
10 for i=0 to 1200-1
20 mpoke i,asc(hex$(i/100))
30 next
40 vmove 0,1
横画面ではスクロール、縦画面ではカーソルの移動により確認すると、それぞれ a
や b
すなわちアドレス 1000
台や 1100
台までVRAMに書き込まれていることがわかった。
VRAMからの読み込みも試してみる。
「テキストVRAMサイズは1000バイトあります」と書かれているので、何も考えないでいるとテキストVRAMサイズは1000バイトしかないと思ってしまうだろう。
しかし、実際のテキストVRAMサイズは、特にTFT液晶モードにおいて1200バイトある可能性がある。
そこで、以下のプログラムで vmove
によりメモリー配列に書き込まれるデータの量を調べてみた。
10 for i=0 to 2000
20 mpoke i,&HFF
30 next
40 vmove 500,0
50 for i=0 to 1999
60 if mpeek(i)==&HFF && mpeek(i+1)<>&HFF then print "start:";i+1
70 if mpeek(i)<>&HFF && mpeek(i+1)==&HFF then print "end:";i+1
80 next
これは、以下を行うプログラムである。
- メモリー配列の先頭2001バイトに &HFF を書き込む
- メモリー配列のアドレス500からVRAMを読み込む
- メモリー配列のデータが &HFF でなくなった部分がどこかを調べる
結果は、ビデオ出力モード、TFT液晶横画面モード、TFT液晶縦画面モードにおいて、それぞれ以下のようになった。
結果、ビデオ出力モードを含む試したすべてのモードにおいて
start:500
end:1700
と出力された。
これは、vmove
で指定したアドレスより前にはデータが書き込まれておらず、指定したアドレス以降1200バイトに書き込みが行われていることを示す。
1000バイトしか書き込まれないと思い込んでプログラムを作ってしまうと、予期せぬデータの破壊に繋がる罠であるといえるだろう。
まとめ
今回の調査で、以下のことがわかった。
-
cpoke
によるキャラクターパターンの設定は、TFT液晶モードではgprint
には効かないのに加え、ビデオ出力モードでは効くprint
や既に画面に表示さている文字に対しても効かない。 -
cpoke
によるキャラクターパターンの設定は、ビデオ出力モード・TFT液晶モードともにcpeek
によるキャラクターパターンの取得には反映される。 - &H80台や&H90台のキャラクターは、TFT液晶モードでも、ビデオ出力モードと同様に
print
ではグラフィックや罫線となるが、gprint
では謎の文字となり、さらに8×8の範囲外に描画される謎の現象も発生する。 -
vmove
コマンドは、TFT液晶の画面全体(1200バイト)のデータをVRAMに書き込める。ただし、- TFT液晶横画面モードでは、VRAMに書き込んだだけでは画面に反映されず、スクロールなどのキッカケがないと反映されない。
- TFT液晶縦画面モードでは、横画面モードと違って、スクロールしてもVRAMに書き込んだ内容は画面に反映されない。カーソルを動かすと、カーソルが乗ったところはVRAMに書き込んだ文字が表示される。
-
vmove
コマンドによりVRAMからメモリー配列への読み込みを行うと、1200バイトのデータがメモリー配列に書き込まれる。これはビデオ出力モードでも同じである。- 公式のコマンド一覧の表現から、1000バイトしか書き込まれないと誤解しないように注意!