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

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

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

エラーが発生しました。

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

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

エピ8 プログラムをRUNしましょう


 ***


 エピ8 プログラムをRUNしましょう


 ***


 初期化処理からメインループへと解読が進みました。


 今ならプログラムを入力して、直接実行命令文でプログラムを実行したりできるはずです。


 そうです。プログラムをRUNしましょう。プログラムが動作する全体像を把握します。


 ***


 まず、プログラムを入力します。


 プログラムは文番号を付けた命令文であればよくて、何でもよいのですが、ここは簡単そうな "END" にします。


  10 END


 すると、4806h 以降のメモリに記憶されます。


  4806: 0C 48 0A 00 8F 0D

  480C: 00 00 ...


 4806h 番地の 480Ch は次文への番地ポインタで、続く 000Ah = 10 が文番号、8Fh が "END" の中間コードです。ODh は終端。


 *


 "RUN" したらいきなり "END" って、ヒドイよね(笑)。


 *


 準備ができたので、"RUN" を入力します。


 直接実行命令文はエピ7で解読しました。メインループから 19CBh 番地に行って、中間コードから分岐先の番地を求めて、RET 命令でジャンプします。


 "RUN" の場合は、中間コードは 83h で分岐先は 1CA5h 番地です。


  1CA5: _1973h() # [4577h] = 00h; "RESTORE" 命令と同じ

  1CA8: A = 00h

  1CA9: [457Ah] = A # ファイル関係の状態(?)を 00h に設定

  1CAC: [4565h] = A # プログラムの実行状態を 00h に設定

  1CAF: _165Ah() # [HL] が 3Ah 以上か判定

  1CB2: jr(NC,1CC2h)


 "RUN" の後ろに数字が続くなら "GOTO" と同じ処理(1CB4h〜1CBFh)をしますが、無い場合は 1CC2h 番地に行きます。


  1CC2: _184Ah() # ワークエリアの初期化

  1CC5: _186Fh() # ワークエリアの初期化

  1CC8: HL = 4806h # プログラムの先頭番地

  1CCB: jr _1CBFh


  1CBF: jp _19B9h


 ワークエリアを初期化して、HL をプログラムの先頭にセットします。"RUN" と "GOTO" の違いは、このワークエリア等の初期化の有無ですね。

 いずれにしても 19B9h へとジャンプします。1CBFh 番地を経由しているのは、こうするとコードサイズが1バイト削れるからです。


 19B9h 番地では、次文への番地ポインタ・文番号・命令文への番地ポインタを処置します。HL はプログラムの先頭 4806h を指していて、プログラムは 480Ch, 000Ah, 8Fh, 0Dh でしたね。


  19B9: DE = 47FDh

  19BC: BC = 0004h

  19BF: LDIR # 番地と文番号を 47FDh〜4800h に転送

  19C1: [4801h] = HL # 命令文の番地を 4801h,4802h に転送


 LDIR とは、HL 番地から DE 番地に BC バイトを転送する便利な命令です。転送が終了すると HL と DE は BC だけ増加して、BC はゼロになります。


 これによって、


   番地(47FDh,47FEh) = 480Ch

  文番号(47FFh,4800h) = 000Ah

  命令文(4801h,4802h) = 480Ah


 となります。


 次は、47FDh,47FEh 番地を調べてプログラム(命令文)があるかを確認します。0000h だったら命令文がないことを意味するので 1B13h("END")に行きます。プログラムは 4806h 以降にあるので 47FEh で判定すれば十分ですね。


  19C4: A = [47FEh] # = 48h

  19C8: if A==00h: jp _1B13h


 ここでは 47FEh 番地は 48h なのでジャンプせずに次に進みます。


 続いて中間コードの分岐処理(19CBh 〜)です。が、直接実行命令文の場合と同じなので省略しますね。中間コード 8Fh の場合は 1B13h にジャンプします


 "END" 命令を実行します。


  1B13: _13BFh() # [4565h] = 01h

  1B16: [4801h] = HL # HL = 480Bh

  1B19: jp _124Dh


 13BFh のルーチンをコールしてプログラムの実行状態 4565h を 01h に設定、命令文への番地ポインタ4801h の値を更新して 480Bh にします。4801h を更新するのは "CONT" 命令で再開できるようにするためですね。


 そして、メインループの先頭(124Dh)に行きます。


 これが "END" 命令です。


 *


 1B16h 番地のコードで 4801h 番地に転送した HL(=480Bh)は、このプログラムの場合は文の最後を指していて、480Bh 番地の値は 0Dh です。


 今回は END なので終了する(124Dh に行く)のですけど、END ではない命令文の場合は、...例えば "REM" などの場合は終端(0Dh)に着いたら 19A4h 番地に飛びます。


  19A4: if [HL]!=0Dh:

  19A8:  _169Ah(3Ah) # 3A = ":"

  19AC:  [4801h] = HL

  19AF:  jr 19CBh

  19B1: HL = [47FDh]

  19B6: if [HL] == 0000h: jp 124Dh # main-loop

  19B9: ...


 19A4h のルーチンでは、終端に来ているかと、次文の番地 [47FDh] を確認します。次文の番地が 0000h なら終了でメインループに行きます。ここでさりげなく HL が更新されてますね。


 それから...、19B9h のルーチンで番地・文番号・命令文を更新して、番地を確認して命令文があれば分岐処理をして命令文を実行します。


 *

 *

 *


 ここまでの流れを整理するとこんな感じになります。


    * メインループにて、直接実行命令文 "RUN" を実行(HL=4459h)

    ↓

    * 19CBh: 中間コードによる分岐(RUN:83h なら 1CA5h にジャンプ)

    ↓

    * 1CA5h: "RUN" 命令を実行(HL=4806h, 19B9h にジャンプ)

    ↓

  ┏→* 19B9h: 番地・文番号・命令文を設定(19C4h に続く)

  ┃ ↓

  ┃ * 19C4h: 番地を確認(0000h なら終了、それ以外は 19CBh に続く)

  ┃ ↓

  ┃ * 19CBh: 中間コードによる分岐

  ┃ ↓

  ┃ * nnnnh: 命令文を実行(...、19A4h にジャンプ)

  ┃ ↓

  ┗━* 19A4h: プログラム続行かを判定(続行なら 19B9h に続く)


 *


 "END" 命令を実行するかプログラムの最後になるまでプログラムの実行は続きます。


 *


 あ、それから。終端の 0Dh だったら次の文に進むのですけど、文によってはマルチステートメントで続きがあることがあります。

 

  10 A=1:B=2

 

 のような場合なら、":" の続きを実行します。


 ***

 **

 *


 プログラムを "RUN" しました。


 ここまで長かったのですが "RUN" 自体は簡単でした。文番号の処置をすれば、あとは直接実行命令文と同じですから。


 他に "CONT" や "NEW"、"CLR" も解読できています("BYE" もね)。


 "LIST" は画面が必要なのでハードルが高いかもです。とすると、次は "LOAD" かな。


 プログラムを LOAD できると夢が広がる気がする。


 ***

 **

 *


 直接実行(が可能な)命令文とは、中間コードが 80h 〜 A8h である命令です。


 具体的には、


  SAVE, LOAD, VERIFY, LIST, RUN, CONT, NEW, CLR, BYE


 などの、ほぼ直接実行でしか使わない命令と、


  FOR, NEXT, IF, STOP, END, GOTO, GOSUB, RETURN, ON,

  DEF FN, REM, LET, DIM, PRINT, INPUT, GET, CURSOR,

  SET, RESET, MUSIC, TEMPO, WOPEN, ROPEN, CLOSE,

  DATA, READ, RESTORE, POKE, INP#, OUT#, LIMIT, USR(,


 ですね。


 ...、"RETURN" 命令も直接実行できるんだ。GOSUB した後に BREAK なり STOP した状態で、メインループにて "RETURN" を入力してみたらできた。


 "STOP" 命令や "END" 命令は、直接実行命令文として実行できても、...ですけど、実行はできる。逆に、"NEW" 命令をプログラムとして実行すると、


  10 NEW


 として RUN したら自分が消えるよ。


 実行できるか否かと、できて意味あるかは別ってことですね。


 ***


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


 ***

2026.2.7 推敲

2026.2.11 加筆と推敲

2026.2.19 微推敲

2026.2.20 推敲

2026.2.24 微推敲

2026.3.18 微推敲


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

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