[新連載]復活!TINY BASIC
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
すべてはここからはじまりました。
中日電工も。
40年前を振り返りつつ新連載です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
[第32回]
●メインループ(4)
今回はテキスト行の追加作業についての説明です。
ST4:から先でその作業が行なわれます。
前回の終わりのところで書きましたように、入力した行と同じ行番号の行がみつかった場合はその行をまず削除してからST4:を実行し、同じ行番号の行が存在しなかったときは何もしないでST4:を実行します。
ST4:では最初にPOP Bが実行されます。
アドレス00F4でCALL FNDLNが実行され、テキストエリアの削除対象行の先頭アドレスがDEレジスタに入れられます。
その後00F7でPUSH Dの実行によってDEが保存されます。
ST4:のPOP Bによって、そのとき保存されたテキストエリアの削除対象行の先頭アドレスがBCに入れられます。
実際にはST4:に来たときには削除対象行は削除済みなので、BCの値はその後ろの行が前詰めされた結果、追加挿入のために後ろに下げるエリアの先頭アドレスを示していることになります。
入力バッファの行データはこのBCで示されるアドレスに挿入されることになります。
行データを挿入するためにはその長さ(バイト数)分のエリアを空ける必要があります。
その作業のためにHLにはTXTUNFの値を入れます(010CのLHLD TXTUNF)。
TXTUNFには現在のテキストエリアの最後+1のアドレスが入っています。
次の010FのPOP PSWでAレジスタに入力行の長さ(バイト数)が入ります。
この値はアドレス00F3のPUSH PSWで保存したものです([第28回]のプログラムリスト参照)。
これで1行分のエリアを空けるためのデータが揃いました。
後の作業で使うためにHLを保存しておきます(0110 PUSH H)。
実際にその作業に入る前に行削除についての確認をします。
TINY BASICでは行番号のみを入力したときはその番号の行が削除されます。
行番号のみを入力したときは16進数に置き換えられた行番号(2バイト)と最後の0Dコードの合わせて3バイトが入力行になります。
そこでCPI 3、JZ RSTARTを実行します。
前回の作業によって対象行はすでに削除済みですから、もし行番号のみの入力であったときにはそれ以後の作業は不要なのでそのままRSTARTに戻ります。
ということなので実際の行挿入のためのエリアを空ける作業はアドレス0116からになります。
HLには現在のテキストエリアの終わりのアドレス+1が入っています。
そこに挿入する行の長さを加算します(0116〜011B)。
そのあとTXTENDとの比較を行ないます。
RTS 4はHLとDEを比較するサブルーチンです([第12回]参照)。
比較の結果HL>=DEならテキストエリアオーバーですからSORRY表示ルーチンにジャンプします。
実際にはHLの値はテキストエリアの終わりのアドレス+1ですから、HL=DEならぎりぎりセーフのはずです。
おそらくそうするためにはJZ命令を追加しなければならないため、するとプログラムのために余分なメモリが必要になるのでここはプログラムメモリサイズのほうを優先したのでは、と思います。
テキストエリアのチェックがOKならば新しいテキストエリアの終わりのアドレス+1(HLレジスタの値)をTXTUNFに入れます。
0126のPOP Dによって0110 PUSH Hで保存した旧TXTUNFの値がDEに入ります。
そのあとCALL MVDOWNを実行します。
MVDOWNは[第29回]で説明しました。
BCの値は上のほうで説明しましたように挿入行のためのエリアを空けるため後ろに下げるエリアの先頭アドレスが入っています。
DEの値は現在の実際のテキストエリアの終わりのアドレス+1です。
HLの値は後ろにずらして挿入行のためのエリアを空けたあとのテキストエリアの終わりのアドレス+1です。
MVDOWNはDE−1のアドレスのデータをHL−1のアドレスにコピーすることからコピーを開始します。
言い換えるとテキストエリアの最後のアドレスの値を新しいテキストエリアの終わりのアドレスにコピーすることから作業を開始します。
そこから前の方へ、DEとHLを−1しながらコピー作業を進めていき、DE=BCになったところで最後のデータをコピーしてそこで終ります。
そのようにして確保した空きスペースに入力バッファの入力行を挿入します。
アドレス012AのPOP Dから後ろの作業です。
このPOP Dと次のPOP Hはずっと前の方で保存した値です。
これはもうメインループの最初から見なければわかりません。
メインループの全体のリストは[第26回]にあります。
DEにはアドレス00F0のPUSH Dで保存した入力バッファ内の入力行の先頭アドレスが入ります。
HLにはその前の00EFのPUSH Bで保存した入力行の終わりのアドレス+1が入ります。
BCにはMVDOWNを実行する前からの値が入っています。
BCの値はMVDOWNを実行しても変化せず、入力行を挿入する先の先頭アドレスを示します。
そしてCALL MVUPを実行します。
MVUPも[第29回]で説明しました。
そこではBC<DEが必要と書きましたが、今回のMVUPについてはBCで示すアドレスとDE、HLで示すアドレスは完全に別のアドレスで重なりがありませんから、BC<DEである必要はありません。
MVUPによって入力バッファの中の入力行がBCで示すテキストエリアのアドレスから後ろにコピーされます。
コピー(動作としては挿入)後はST3:に戻って次の入力を待ちます。
復活!TINY BASIC[第32回]
2020.7.4upload
前へ
次へ
ホームページトップへ戻る