0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ORANGE picoAdvent Calendar 2023

Day 22

ORANGE pico のTFT液晶とフォントとVRAMと

Posted at

ORANGE pico のTFT液晶モードの挙動をもう少し調べてみた。

cpoke によるパターンの設定は効くか?

ORANGE pico では、cpoke という、キャラクターコードに対応するパターンを設定するコマンドがある。
これまで、cpoke について、ビデオ出力モードでは

  • テキスト画面に表示するキャラクターのパターンを変更できる
  • 設定は、既に画面に表示されているキャラクターにも遡って適用される
  • gprint コマンドで使用するフォントはなぜか変更されない

ということがわかっている。
以下の画像は、「hello world」を出力させた後、cpoke コマンドにより空白 (&H20) のパターンを音符 (9) に変更し、再び「hello world」を出力された様子である。
テキスト画面への出力では空白が音符に置き換わっているが、gprint コマンドによるグラフィック画面への出力では空白が空白のまま出力されている。

ビデオ出力モードで cpoke を試す

同様の実験をTFT液晶モード (spitft 1) で行うと、以下の画面になった。

TFT液晶モードで cpoke を試す

以下すべてにおいて、cpoke による設定は反映されていないことがわかる。

  • cpoke の実行前に表示されていた文字
  • cpoke の実行後にUART入力を反映して出力された文字
  • cpoke の実行後に print コマンドにより出力された文字
  • cpoke の実行後に gprint コマンドにより出力された文字

さて、ビデオ出力モードでは、cpoke によるキャラクターパターンの設定は cpeek により読み込まれるキャラクターパターンにも影響する。

ビデオ出力モードで cpoke が cpeek に反映される

TFT液晶モードでも試してみると、ここは同様に反映されるようである。

TFT液晶モードでも cpoke が cpeek に反映される

&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液晶モードともに罫線の文字が出力された。

ビデオ出力モードでの出力
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の領域からはみ出して描画されたりする現象を観測できた。

gprint による一部の文字の出力が print と違うことを確認できる

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

以下が、プログラムの実行直前の様子である。

VRAMに書き込むプログラム 実行直前

プログラムを実行し、さらにキーを押して終了させた。
130行目の位置に「OK」が出ている。
にもかかわらず、VRAMへの書き込みは反映されず、入力したプログラムがそのまま表示されている。

VRAMに書き込むプログラム 実行後

カーソルを画面の一番下まで移動させ、さらにCRを送信してスクロールさせると、VRAMに書き込んだ内容が反映された。

スクロールにより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

横画面ではスクロール、縦画面ではカーソルの移動により確認すると、それぞれ ab すなわちアドレス 1000 台や 1100 台までVRAMに書き込まれていることがわかった。

横画面でのVRAM書き込み結果
縦画面での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

これは、以下を行うプログラムである。

  1. メモリー配列の先頭2001バイトに &HFF を書き込む
  2. メモリー配列のアドレス500からVRAMを読み込む
  3. メモリー配列のデータが &HFF でなくなった部分がどこかを調べる

結果は、ビデオ出力モード、TFT液晶横画面モード、TFT液晶縦画面モードにおいて、それぞれ以下のようになった。

ビデオ出力モードでVRAMからの読み込みを試す
TFT液晶横画面モードでVRAMからの読み込みを試す
TFT液晶縦画面モードでVRAMからの読み込みを試す

結果、ビデオ出力モードを含む試したすべてのモードにおいて

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バイトしか書き込まれないと誤解しないように注意!
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?