目次次へ番外編 Chap.7 命令語インタプリタを改造する(2)

(2010/12/26 本文中のVisual Basicプログラムは、VB5.0のものです。VB.NETとは一部異なる部分があります。)

Chap.6では、命令語インタプリタの改造について検討しました。
今回は、Visual Basic 5.0で書いた命令語インタプリタのソースを実際に改造することにします。
なお、改造の元となるソースプログラムは、番外編Chap.2で作成したプログラム(bang10b.zip)です。

7.1 導通状態スタックを設ける(改造1)
まず、回路ブロックの演算結果を一時的に記憶しておくスタック(導通状態スタック)を設けます。(リスト7.1)
前回説明したように、スタックの機能をシフトレジスタで構成するため、スタックポインタは必要ありません。

リスト7.1 導通状態スタックを設ける(1行挿入)
'変数定義

Dim Prg(1023) As String '命令語プログラム
Dim LastPrg As Integer '命令語プログラム最終ポインタ+1
Dim RunFlg As Boolean 'スキャン実行許可フラグ
Dim m(&HFF) As Boolean 'I/Oメモリ
Dim Reg As Integer '導通状態レジスタ
Dim Cmd As String 'I/Oメモリの変更指示(文字列)
Dim FileName As String '命令語プログラムファイル名
Dim Stk(7) As Integer '導通状態スタック (99/07/19)

また、命令語の処理の中で、このスタックに対するPUSH動作、PULL動作の手続き(または関数)が必要となるため、ここで作成しておきます。(リスト7.2)

リスト7.2 PUSH動作、PULL動作の手続き(または関数)を新規作成
'名称:PUSH動作
'機能:スタック(配列)にデータをPUSH(シフト)する
'99/07/19 新規作成
Private Sub PushStk(x() As Integer, y As Integer)
x(7) = x(6)
x(6) = x(5)
x(5) = x(4)
x(4) = x(3)
x(3) = x(2)
x(2) = x(1)
x(1) = x(0)
x(0) = y
End Sub

'名称:PULL動作
'機能:スタック(配列)からデータをPULL(シフト)する
'99/07/19 新規作成
Private Function PullStk(x() As Integer) As Integer
PullStk = x(0)
x(0) = x(1)
x(1) = x(2)
x(2) = x(3)
x(3) = x(4)
x(4) = x(5)
x(5) = x(6)
x(6) = x(7)
x(7) = 0
End Function


7.2 LD命令、LDNOT命令の動作を変更する(改造2)
次に、LD命令、LDNOT命令の動作を変更します。
従来の命令語インタプリタでは、LD命令、LDNOT命令の動作は、導通状態レジスタにデータをロードするだけでした。
改造後の命令語インタプリタでは、導通状態レジスタにデータをロードする前に、現在の導通状態レジスタの内容を導通状態スタックに退避(PUSH動作)します。(リスト7.3)

リスト7.3 LD命令、LDNOT命令の動作を変更(2行挿入)
Case "LD" 'LD命令のとき
i = i + 1
Call PushStk(Stk(), Reg) '導通状態レジスタをスタックに退避 (99/07/19) Reg = m(Val("&H" + Prg(i)))
Case "LDNOT" 'LDNOT命令のとき
i = i + 1
Call PushStk(Stk(), Reg) '導通状態レジスタをスタックに退避 (99/07/19)
Reg = Not (m(Val("&H" + Prg(i))))

7.3 ANDSTACK命令、ORSTACK命令を新規作成する(改造3)
次に、ANDSTACK命令、ORSTACK命令を新規作成します。
これらの命令は、LD命令またはLDNOT命令でスタックに退避したデータと導通状態レジスタとを、AND結合またはOR結合する命令です。(リスト7.4)

リスト7.4 ANDSTACK命令、ORSTACK命令を新規作成
Case "ANDSTACK" 'ANDSTACK命令のとき (99/07/19)
Reg = Reg And PullStk(Stk()) '(99/07/19)
Case "ORSTACK" 'ORSTACK命令のとき (99/07/19)
Reg = Reg Or PullStk(Stk()) '(99/07/19)


7.4 バージョン表示を変更(改造4)

最後に、バージョン表示をV1.0から、V1.1に変更します。(リスト7.5)

リスト7.5 バージョン表示(1行削除、1行挿入)
'名称:フォームロード処理
'機能:起動時の初期設定

Private Sub Form_Load()
'(99/07/19) frmMain.Caption = "番外編 - 命令語インタプリタ V1.0"
frmMain.Caption = "番外編 - 命令語インタプリタ V1.1" '(99/07/19)
lstMon.Font = "MS ゴシック"
lstPrg.Font = "MS ゴシック"
Timer1.Interval = 100 '100ms毎にタイマイベント発生
End Sub


7.5 動作確認

以上の改造1〜改造4をおこない再コンパイルすると、改造後の命令語インタプリタの実行ファイル(EXEファイル)ができあがります。
では、この作成した命令語インタプリタの動作を、図7.1のテストプログラムで確かめてみましょう。

図7.1 テストプログラム(ラダー図)

このラダー図は、回路ブロックの結合があるため、従来の命令語インタプリタでは、実行できませんでした。
しかし、改造後の命令語インタプリタでは、リスト7.6のように命令語に変換して、実行することができます。

リスト7.6 テストプログラム(命令語)
/* ANDSTACK,ORSTACKテスト */
LD
00
LDNOT
10
LD
20
AND
21
ORSTACK
ANDSTACK
OUT
30
END

動作を確かめたい方は、改造後の命令語インタプリタのソースと実行ファイル(bang11.zip)を、ダウンロードして、実際に動かしてみてください。

さて、次回からは、改造後の命令語インタプリタで「ラダー図でメモリを作る」に挑戦します。

目次次へ