表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
35/36

エピ26 MZ80のカーソル制御のこと(続) - 1173h番地を整理


 ***


 エピ26 MZ80のカーソル制御のこと(続) - 1173h番地を整理


 ***


 カーソル制御について調べていましたが、謎が多すぎて先に進めなくなりました。実は1つの謎を放置して先に進んだら、謎が次の謎を呼び出していてね。クリーピングコインは仲間を呼んだ!


 冷却して、リークメモリのフラッシュもしたので再度挑戦をしてみます。


 1173h 番地のことを整理して、残る C7h [DEL] と C8h [INS] に取り組みましょう。


 ***


 1173h 番地について見直しました。


 00h なら未接続で、00h 以外なら接続中を意味するのは間違いないはずです。

 ですが、どの行と接しているのかを誤解していました。


 正しくは、


   [1173h+Y+0]!=00h ならば、Yは「前行」と接続中

   [1173h+Y+1]!=00h ならば、Yは「次行」と接続中


 です。なお Y=[1172h] です。Y は 0〜24 の範囲です。


 次のように並べて見たら、[1173h+Y+1] は Y と Y+1 の行の接続の有無を示すのだな、と分かった感じになりました。どうでしょうか?


  [1173h] 0 [1173h+1] 1 [1173h+2] 2 [1173h+3] ...


  ... [1173h+23] 23 [1173h+24] 24 [1173h+25], [1173h+26]


 なお。[1173h] と [1173h+25], [1173h+26] が用意されているのは、ディスプレイ表示やスクロールアップの処理の都合のようです。これがあると条件分岐を減らせるのです。番兵くんみたいだ。


 *


 復習していて気が付いたのです。GETL で取得する行は 1173h を参照して、


   if [1173h+Y+0]!=00h: BC=0050h; H=Y-1; L=00h

   elif [1173h+Y+1]!=00h: BC=0050h; H=Y; L=00h

   else:          BC=0028h; H=Y; L=00h


 とするのです。(X=L,Y=H) の座標から [BC] バイトを取得する。つまり、前行と接続中なら Y-1 と Y の2行を、次行と接続中なら Y と Y+1 の2行を、どちらとも未接続なら Y の1行を取得する。


 *


 ディスプレイ表示 0DB5h を再確認します。X=[1171h], Y=[1172h] です。


   if X==27h and [1173h+Y+0]==00h:

     [1173h+Y+1]=01h

     [1173h+Y+2]=00h


 X=39 で1文字を表示して、カーソル位置を次の行の先頭に移動する場合、


  ・前行と未接続なら次行と接続中にして、次行は、次行未接続にする。

  ・前行と接続中なら更新しない。


 ...、と言うことです。


 ある Y について [1173h+Y+1] が 01h であるときは [1173h+Y+0] と [1173h+Y+2] は 00h であるのです。


 01h の前後は必ず 00h であり、01h は連続しない。...、3行の連結はしない。


 *


 境界値についてチェックします。境界テストは基本です。


 [1173h+0] は、0DB5h のルーチンで 01h になることは無いですね。Y=0 の前行は無いですから当然ね。


 [1173h+1] は 01h なることはある。それでスクロールアップで [1173h+0] が 01h になったら、2回目のスクロールアップをする。01h のあとは 00h なので3回目は無くて [1173h+0] は 00h になる。


 [1173h+24] は 01h になる。X=39,Y=23 でディスプレイ表示して Y=24 の行と接続したとき。


 [1173h+25] は X=39,Y=24 でディスプレイ表示したら 01h になり、[1173h+26] は 00h になる。続いて [→] の制御でスクロールアップして [1173h+25] は 00h になる。Y=24 の次行は無いから未接続でOK!


 *


 これでスッキリしました。


 *


 **


 ***


 C7 [DEL] です。MZ80の [DEL] は、Back Space のことです。MZ80には Delete キーは無いのよ。


  _0EF8: #C7 [DEL]

    if [1171h]==0000h: jp _0FDEh # POPs&RET, if X=0,Y=0

    elif [1171h]!=00h: jp _0F1Dh # if X!=0

    elif [1173h+[1172h]]!=00h: jp _0F1Dh # if 前行接続中

    else: # X==0 and 前行未接続

      HL=_0FB1h() # カーソルの番地をHLにセット

      _0DA6h(); dec HL; [HL]=00h # (X=39,Y-=1)を00hに

      jp 0EAEh # [←]


  _0F1D: # X!=0 or 前行接続中

    if [1173h+[1172h]+1]==00h: # if 次行と未接続

      BC=28h-[1171h]

    else:

      BC=50h-[1171h]

    HL=_0FB1h(); DE=HL-1; _0DA6h(); LDIR; dec HL; [HL]=00h

    jp 0EAEh # [←]


 X,Y座標と前後の接続状態による処理分岐は、ゆっくり読めば分かりますね。


 0F1Dh のルーチンでは [DEL] するとカーソル位置以降の文字が左に移動するので、その際に1行分なのか2行分なのかを 1173h で判定していますけど。前行接続中なら次行とは未接続であることを考慮すれば、分かるよね。


 ***


 BASICの環境は、パソコンのフルスクリーン・エディタとは違うことが良く分かりますね。


 ***


 C8h [INS] です。カーソル位置以降を1つ右に移動して、カーソル位置をスペースにします。


  _0F49: #C8h [INS]

    if [1173h+[1172h]+1]!=00h: # 次行と未接続

      C=00h; H=[1172h]; L=27h

    else:

      C=01h; H=[1172h]+1; L=27h

    # HLは行末か次行の末

    HL=_0FB4h(HL) # XY座標を番地に変換

    if [HL]!=00h: # 行末が詰まっているとINSできない

      jp _0FDEh # POPs&RET

    # 以下で B,HL,DE をセットして転送(LDDR相当の処理)

    B=27h-[1171h]

    if C!=00h: B=B+28h #28h=40

    DE=HL; HL=HL-1; _0DA6h()

    while(B>0):

      [DE]=[HL]; [HL]=00h; dec HL; dec DE; dec B

    jp _0FDEh # POPs&RET


 なるほどネ、と言う感じです。


 ループの中で [HL]=00h と毎回ゼロクリアしているのは、ループ終了後にすれば良いのではないかな。


 ***

 **

 *


 謎は解けた。いよいよキャスティング完了か?


 ***


 間違いの指摘とか疑問とか、ご意見・ご感想とかありましたら、どうぞ感想欄に!


 ***

2026.5.3 微推敲

2026.5.8 エピタイ修正


評価をするにはログインしてください。
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

↑ページトップへ