標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第578回]

●XPの画面表示のゴミ対策が間違っていました

前回説明をいたしました、下記の、改行を行った後のゴミを消すために考えたプログラム部分なのですが、全く機能していませんでした。

		 x=wherex();y=wherey();
		 if (y>=25)
			{
			for(i=0;i<80;i++)putc(0x20,stdout);
			y0=y-24;
			gotoxy(x,y0);
			gotoxy(x,y);
			}

これでうまくいったつもりだったのですが、なにしろもう眠くて、全然うまくいっていなかったのを見落としてしまっていました。
うう。トシは取りたくないものです。

最下行のクリアもうまくできていますし、それから1行余分にスクロールしてしまっていたのも、ちゃんと取り戻していますから、ちょっと見にはうまくいった、と思ってしまったのです。
で、このあとすぐに[PageUp]キーを押して[pagemode]にしてしまったので、この画面が正しくないことに気がつきませんでした。

よーく見ますと、カーソルが画面の一番上に行ってしまっています。
gotoxy(x,y0);が実行された結果なのですが、そのあと、gotoxy(x,y);で、画面の最下行にカーソルが移動するはずなのですが…。
どういうわけか、移動してくれません。
いろいろ試してみたのですが、結局駄目でした。

画面右のスクロールバーが少し下がっています。
そのこと自体はまともなのですが、どうやらこの画面のように、画面バッファが働いている状態のときには、gotoxy()で「過去」に戻ることはできるのですが、一旦「過去」に行ってしまうと、その位置からは、gotoxy()で画面の下方向に移動することはできなくなってしまうようです。

どうも画面バッファの仕組みが、私が当初考えていたような、柔軟な構造ではなくて、かなり硬直したもののようです。
gotoxy()で画面バッファの前方に戻ると、そのポジションが最終のカーソル位置になってしまい、そこから下方へはgotoxy()では進むことができなくなってしまいます。
そのポジションから新たにprintf()やputc()で文字を表示したり、改行を行わせることで下方へ進むことはできます。
そういう仕組みなのですねえ。

そういう仕組みだとすると、せっかく考えたプログラムも役には立ちません。
また考え直しです。

●なんとか解決できたのですけれど

結局わかったことは、画面バッファを利かせてはだめだ、ということでした。
画面バッファが働いている状態、つまりスクロールバーが下がっている状態のときには、gotoxy()で画面バッファ内を移動することはできません。
こちらが意図している通りにgotoxy()を使おうとしますと、どうしても画面バッファの働きをキャンセルするしかない、という結論になりました。

そのように考えて、なんとかたどりついたプログラムがこれです。

		 y=wherey();
		 if (y<=25)
			{
			gotoxy(1,1);
			for(i=cursor-1920;i<cursor;i++)putc(vram[i],stdout);//80*24
			for(i=0;i<80;i++)putc(0x20,stdout);
			gotoxy(1,1);
			gotoxy(1,25);
			}

最初のgotoxy(1,1)で画面バッファのトップまで戻ります。
これでスクロールバーは上まで戻ります。
こうすると画面バッファの働きを封じることができますが、そのかわり画面の表示も一番最初の画面に戻ってしまいます。
そこで、プログラムで保存している「画面バッファ」(vram[])の値をもう一度一画面分表示します。
そうしておいてから、画面最下行をクリアして、goto(1,1)で、1行余分にスクロールされていたのを元に戻してから、gotoxy(1,25)でカーソルを画面最下行に移動します。
このようにすると、gotoxy(1,1)の後でも、gotoxy(1,25)は正しく機能します。


こんどこそ本当にうまくいきました。
カーソルが画面最下行に来ています。
画面右のスクロールバーは上まで上がっています。

ということは、XPの画面バッファは今は働いていない状態です。
XPの画面バッファとしては、これが一番上の画面なので、これよりも前に戻ることはできません。
この状態なら、表示画面内をgotoxy()でカーソル移動することができます。

しかしXPの画面バッファが利いていないだけで、Z80BASICのpagemodeはこの状態から働かせることができます。

[Page Up]キーで、画面をさかのぼって表示させることができます。

スクロールバーは上に上がったままです。

ところで、今回のプログラムは、改行が実行されると、画面バッファを一番最初のポジションに戻してしまいますが、その操作が働く直前の状態を参考までに見ていただくことにいたします。

BASICのプログラムに少し追加して、プログラムが終わってシステムに戻って改行が行われる直前で表示を停止させたままにしてみます。


40行を追加しました。
INKEY$はキーボードからの入力をチェックする命令です。
キーが押されると、そのキーに対応する文字が入ります。キーが押されていないときは、つねにスペースが入ります。

プログラムを実行してみました。

最後のデータ1000が表示されたところで画面が停止しています。
まだ改行は行われていません。
かなり大量のデータを連続して表示しましたから、XPの表示バッファが働いていて、スクロールバーが下がっています。

ここで何かキーを押すと、プログラムが終了して、上の方でお見せした画面になります。

ということで、プログラムとしては、間違いなく動作するようにできたのですけれど、しかし、これはあまり感心できるプログラムじゃありません。
改行のたびに1画面分を書きかえるのですから、それだけ実行時間もかかってしまいます。

とにかく、XPの画面バッファ対策としてここまで作ってきた、ということで、一応の成果はあった、と思います。
しかし現実的な対応としては、やはり、コマンドプロンプトのプロパティを操作して、画面バッファのサイズを25行にする、というのが最良の方法、ということになりそうです。

うわあ。なんだかめちゃめちゃ道草をしてしまいました。
なんとかやっと、Z80BASICもまっとうに動作するようになりましたので、これから急いで説明書を仕上げなければいけませんし、ぼちぼち手配しておりましたND80ZV組立キットのパーツも入荷してきましたので、これから少しずつND80ZVの組立についての説明にもかかりたいと思います。

ああ。いけません。
その前に。
[第571回]でRS232Cで受信したデータがところどころ欠落しています、と書きましたが、その後についてまだ書いていませんでした。
そこからずっと、XPでの改行時の問題についてのお話になってしまっておりました。
まずは、お話をもとに戻しまして、次回は、そのデータの欠落についてのお話から始めることにいたします。
2010.8.9upload

前へ
次へ
ホームページトップへ戻る