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

[新連載]復活!TINY BASIC
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
すべてはここからはじまりました。
中日電工も。
40年前を振り返りつつ新連載です。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜



[第27回]


●メインループ(2)

前回は「メインループ」について英語の説明文をもとにしながら説明をしました。
今回は実際のメインループのプログラムリストを見ながらその動作の説明をしていくことにします。
前回を書いた時点では「今までと同じように少しずつプログラムを見ながら説明していけばよい」ぐらいに簡単に考えていたのですが、実際に説明にとりかかってみると、この部分はなかなかに「ホネ」なことがわかってきました。
行きつ戻りつしながら少しずつ説明をしていくことになってしまうかと思います。

前回はメインループ全体のプログラムリストをお見せしたのですが、とても1回では説明できそうにないことがわかりましたので、少しずつ区切って説明をしていくことにします。
下はメインループの前半の部分です。



アドレス00BA〜00D5まではTINY BASICのスタート後に1回だけ実行される初期設定部分なので「ループ」ではありません。
ループになっているのは00D6のST3:から後ろの部分です。
アドレス00BAでは最初にSP(スタックポインタ)にRAMのエンドアドレス(13FF)+1の値1400をセットします(この値については前回を参照してください)。
ST1:ではCALL CRLFで改行したあと’OK’(および改行)を表示します。
PRTSTGはDEで指定する文字列を表示するサブルーチンです
PRTSTGについてはいずれ説明することになると思います。

そのあと”CURRNT”に初期値としてアドレス00CEを入れています。
00CE、00CFの値は0000です。
”CURRNT”の使い方はまだよく確認していません。
英語の説明文によれば、ここには行の先頭の行番号が置かれた位置のアドレスが入るようですが、いずれその目的についてわかってくると思います。
そのあとのST2:では”LOPVAR”と”STKGOS”に初期値0000をセットしています。
この2つの変数についてもそのうちわかってくると思います。

その次の00D6のST3:からがループになっています。
プロンプトマーク>(コード3E)を表示したあとCALL GETLNで入力待ちになります。
GETLNは行データの入力サブルーチンです。
詳細についてはいずれ説明することになると思います。
プログラム行またはコマンドを入力するとその一行を入力バッファに入れてリターンしてきます。
そのとき入力バッファに入った入力の終わりの0Dコードのアドレス+1がDEレジスタに入っています。
PUSH Dでそれを保存したあと、CALL TSTNUMで入力バッファの先頭に行番号があるかどうかを確認します。
TSTNUMは[第15回]で説明しました。
その後ろのRST 5は[第12回]で説明しましたが、多くは文字列の中のブランク(スペース、コード20)をパスするために使われます。
ここでは入力バッファの先頭の行番号の後ろにスペースがあるならばそれをパスしてその次のアドレスをDEレジスタに入れるために使われています。
TSTNUMの実行によってHLレジスタには行番号(16進数)が入りますが、行番号が無い場合にはHL=0000になります。
行番号が0のときもHL=0000になります。
行番号がないか行番号が0の場合にはダイレクトコマンドとみなされます。
そのとき(HL=0000のとき)にはJP DIRECT(ダイレクトコマンド実行ルーチン)が実行されます。
DIRECTについてもいずれ説明することになると思います。
説明順序が逆になってしまいましたがスタックを合わせるためと、このあと下で説明する処理のためにJMP DIRECTの前にPOP Bが実行されます。
これによって先にPUSH Dで保存しておいた入力データの終わりのアドレス(0Dコードが置かれたアドレスの1バイト後ろのアドレス)がBCレジスタに入れられます。

00E9から後ろはHLに0ではない数値(つまり行番号)が入っていたときの処理になります。
このときDEにはTESTNUMを実行した結果、入力バッファの先頭から見て行番号でもスペースでもない最初の文字が置かれたアドレスが入っています。
それをDCX Dで1バイト前のアドレスに戻します(00E9)。
そしてそのDEで示されるアドレスにHレジスタの値を入れて、さらにもう1バイト前のアドレスにLレジスタの値を入れます。
HLには入力された行番号の数値を16進数に直した数値が入っています。
上の処理を実行した結果入力バッファの内容が置き換わります。
入力直後には先頭からASCIIコードで示された最大5桁の行番号数値があって、その後ろにスペースがあって(スペースが無い場合もあります)、その後に命令文が続いています。
それが00E9から00EEの処理によって、16進数に変換された行番号の下位8ビットが先頭に置かれて、次に上位8ビットが置かれて、その後にはスペースをはさまないですぐに命令文が続きます。
このとき入力バッファの命令文が始まる位置アドレスは移動しないでそこから前に行番号の上位8ビット、もう1バイト前に下位8ビットが置かれることを理解してください。
そして行番号の下位8ビットが置かれたアドレスがメモリのテキストエリアに転送される入力行データの先頭アドレスになります。
上の処理によってDEレジスタにはその先頭アドレスが入ります。
00EFと00F0のPUSH B、PUSH DでBCレジスタ(入力行の終わり+1のアドレス)とDEレジスタ(入力行の先頭のアドレス)がスタックに保存されます。
さらにC−Eの結果もPUSH PSWによって保存されます。
C−Eの結果は入力行の長さ(バイト数)です。

そのあとCALL FNDLNが実行されることになるのですが、説明が長くなってしまいましたので今回はここまでで終ります。

復活!TINY BASIC[第27回]
2020.6.29upload

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