はじめに
こちらの記事にてMind開発者の@killyさんより情報共有いただいたMind8の検証用Consoleをベースに一部正規のConsoleのコードを取り込んだ中間コードhellolevel1.mcoをリビルドしましたが、その記事のコメントでkillyさんより別の構成のソースのご提案もいただき、そのバージョンをhellolevel0.mcoとしました。こちらの記事ではこの2つのバージョンの中間コードをC#で代替実装したディスパッチャで処理させてみましたが、それぞれ完走にはいたっておりません。そこでhellolevel1.mcoより若干ステップ数の多いhelloleve0.mcoをhellolevel2.mcoとして退避し、hellolevel1.mcoより若干ステップ数のより少ないhellolevel2.mcoを生成してC#で代替実装したディスパッチャで処理させてみます。
前提条件
Windows11 Pro 22H2
VSCode(Visual Studo Code) 1.86.1
Microsoft Visual C++ 2008 Express Edition
Mind Version 8.0.08 for Windows
C# 12
dotnet-sdk-8.0.204-win-x64
VSCodeの拡張機能
C/C++ for Visual Studio Code 1.18.5 Microsoft
C/C++ Extension Pack 1.3.0 Microsoft
.NET Install Tool 2.0.2 Microsoft
Base language support for C# 2.18.16 Microsoft
C/C++のデバッガはCで実装されているMind8kernelの動作をデバッグ実行で探るために使用します。こちらの記事の環境となります。
カスタマイズConsoleのビルド
killyさんよりご提供いただいた情報に従い、下記のようにカスタマイズConsoleのビルド用のフォルダfilelevel群を作成します。
ビルド用フォルダ構成
今回は下記のようなフォルダ構成となります。filedummyフォルダは起動検証用Consoleのビルド環境です。fileフォルダは正規のソースファイルが格納されたフォルダです。filelevel2フォルダは従来のfilelevel0フォルダです。
filedummyの内容はこちらの記事を、filelevel1,2(旧0)の内容はこちらの記事を参照してください。
C:\developments\vscode\mind8>tree
C:.
├─bin
├─file
│ └─obj
├─filedummy
│ └─obj
├─filelevel0
│ └─obj
├─filelevel1
│ └─obj
├─filelevel2
│ └─obj
├─kernel
│ └─.vscode
├─lib
├─libY
└─sample
お題のMindソースコード
カスタマイズConsoleのconslevel0.srcを起動検証用Consoleのconsdumy.srcに対して正規版ConsoleのConsole.srcから必要部分だけもってきて、下記のように編集します。
スプーリングアドレスは 変数。
入力文字補正アドレスは 変数。
※検索機能初期化アドレスは 変数。
※検索機能終了アドレスは 変数。
グローバル。
"../file/osdefine.src"を コンパイルする。 (DOS/UNIXの指定)
"../file/cswitch.src"を コンパイルする。 (コンパイルスイッチ)
"../file/ckaridef.src"を コンパイルする。 (仮定義)
"../file/cconvar.src"を コンパイルする。 (大域定数/大域変数)
"../file/cerrmsg.src"を コンパイルする。 (エラー定数/エラー登録)
"../file/cconv.src"を コンパイルする。 (数値/文字列変換)
"../file/coutput.src"を コンパイルする。 (Pureな表示系)
"../file/cerror.src"を コンパイルする。 (エラー処理)
ローカル。
立ち上がり要求は ワード変数。
立ち下がり要求は ワード変数。
コンソール初期化・基本部とは (・ → ・)
(しばらくはシステムコールするな)
終了パラメータを クリアし ※CCONST.SRC
エラー文字列初期化し ※CERROR.SRC
空白文字列初期化し ※COUTPUT.SRC
。
各ライブラリ初期化とは 本定義 (・ → ・)
コンソール初期化・基本部し ※本ソース
。
グローバル。
$$COLD_FORTHは 本定義
(プログラム起動時のみの処理)
立ち上がり要求を セットし
立ち下がり要求を クリアし
(ライブラリ初期化処理)
各ライブラリ初期化し ※本ソース
「$$COLD_FORTH&改行&」を $$表示。
※ ~略~
※ 終り(CONSDUMY.SRC) ※
conslevel1.srcとの違いは「各ライブラリ初期化し」の直後に下記の実行がないだけです。
「各ライブラリ初期化後」で このメッセージでスタック検査し
お題のMind8のソースファイル
メインとは
「Hello by mind8」を 表示すること。
ビルド実行
横スクロールしてわかりずらいですが、こちらはC#用環境のため、Mind8コンパイラのライブラリ指定パスにはさきほどのC用環境の上にあるfilelevel0\objフォルダのconslevel0を指定します。
C:\developments\vscode\mind8dispatch>mind hellolevel0 c:\developments\vscode\mind8\filelevel0\obj\conslevel0
日本語プログラミング言語 Mind Version 8.07 for Windows
Copyright(C) 1985 Scripts Lab. Inc.
コンパイル中 .. 終了
Coping.. c:\pmind\bin\mindex.exe --> hellolevel0.exe
C側検証環境でhellolevel0.mcoでのスタートアップ処理を検証するため、hellolevel0.mcoをmindexec.mcoにリネームしてC側検証環境のkernelフォルダにコピーします。
C:\developments\vscode\mind8dispatch>copy hellolevel0.mco C:\developments\vscode\mind8\kernel\mindexec.mco
C:\developments\vscode\mind8\kernel\mindexec.mco を上書きしますか? (Yes/No/All):
Y
1 個のファイルをコピーしました。
お題のMind8の中間コード実行リスト
C側検証環境で、前記手順でコピーしたお題の中間コードファイルをディスパッチャで処理させます。
SqNo mcode mc(dec) mpoint dtp.point dtp+0 dtp+1 rtp.point rtp+0 rtp+1
1 8019 32793 57 1024 0 0 1024 0 0
2 002F 47 51 1024 0 0 1023 0 0
3 0012 18 2931 1024 0 0 1023 0 0
4 0036 54 2932 1024 0 0 1023 0 0
5 0080 128 2935 1024 0 0 1023 0 0
6 0036 54 2936 1024 0 0 1023 0 0
7 0070 112 2939 1024 0 0 1023 0 0
8 803A 32826 2940 1024 0 0 1023 0 0
9 002F 47 119 1024 0 0 1022 0 12544234
10 80B8 32952 2929 1024 0 0 1022 0 12544234
11 0012 18 2921 1024 0 0 1021 0 12550000
12 0036 54 2922 1024 0 0 1021 0 12550000
13 0071 113 2925 1024 0 0 1021 0 12550000
14 8046 32838 2926 1024 0 0 1021 0 12550000
15 8045 32837 163 1024 0 0 1020 0 12549978
16 0012 18 157 1024 0 0 1019 0 12549972
17 0036 54 158 1024 0 0 1019 0 12549972
18 0074 116 161 1024 0 0 1019 0 12549972
19 0020 32 162 1024 0 0 1019 0 12549972
20 0020 32 164 1024 0 0 1020 0 12549978
21 80A3 32931 2927 1024 0 0 1021 0 12550000
22 0036 54 1942 1024 0 0 1020 0 12549978
23 0012 18 1945 1024 0 0 1020 0 12549978
24 016E 366 1946 1024 0 0 1020 0 12549978
25 0020 32 1949 1024 0 0 1020 0 12549978
26 0020 32 2928 1024 0 0 1021 0 12550000
27 0020 32 2930 1024 0 0 1022 0 12544234
28 00A5 165 2941 1024 0 0 1023 0 0
29 00C1 193 2950 1022 14 12550004 1023 14 0
$$COLD_FORTH
30 0020 32 2951 1024 0 0 1023 0 0
31 80C3 32963 58 1024 0 0 1024 0 0
32 00A5 165 3177 1024 0 0 1023 0 0
33 8083 32899 3186 1022 14 12550476 1023 14 0
34 0012 18 1755 1022 14 12550476 1022 14 12544236
35 004E 78 1756 1022 14 12550476 1022 14 12544236
36 00EC 236 1759 1020 0 0 1022 0 12544236
37 0096 150 1762 1022 14 12550476 1022 14 12544236
38 026D 621 1763 1020 0 1 1022 0 12544236
Hello by mind8
39 0020 32 1764 1024 0 0 1022 0 12544236
40 0020 32 3187 1024 0 0 1023 0 0
41 801A 32794 59 1024 0 0 1024 0 0
42 002F 47 53 1024 0 0 1023 0 0
43 00A5 165 2965 1024 0 0 1023 0 0
44 00C1 193 2972 1022 10 12550052 1023 10 0
実行終り
45 801B 32795 2973 1024 0 0 1023 0 0
46 002F 47 55 1024 0 0 1022 0 12544238
47 00A5 165 2952 1024 0 0 1022 0 12544238
48 00C1 193 2963 1022 18 12550026 1022 18 12544238
実行終り時の処理
49 0020 32 2964 1024 0 0 1022 0 12544238
50 004E 78 2974 1024 0 0 1023 0 0
51 0014 20 2977 1022 0 0 1023 0 0
お題の「Hello by mind8」のコンソール出力までは38(同一コード含む)のmcodeを処理すればよく、終了までは51ステップです。hellolevel1の場合は46と60でしたので10ステップ弱の削減となりました。
お題のMind8の中間コードのC#代替ディスパッチャ実行リスト
続いてC#側検証環境で、前記手順でビルドしたお題の中間コードファイルをC#代替ディスパッチャで処理させます。
SqNo mcode mc(dec) mpoint dtp.point dtp+0 dtp+1 rtp.point rtp+0 rtp+1
1 8019 32793 114 1024 0 0 1024 0 0
2 002F 47 102 1024 0 0 1023 114 0
3 0012 18 5862 1024 0 0 1023 114 0
4 0036 54 5864 1024 0 0 1023 114 0
5 0080 128 5870 1024 0 0 1023 114 0
6 0036 54 5872 1024 0 0 1023 114 0
7 0070 112 5878 1024 0 0 1023 114 0
8 803A 32826 5880 1024 0 0 1023 114 0
9 002F 47 238 1024 0 0 1022 5880 0
10 80B8 32952 5858 1024 0 0 1022 5880 0
11 0012 18 5842 1024 0 0 1021 5858 0
12 0036 54 5844 1024 0 0 1021 5858 0
13 0071 113 5850 1024 0 0 1021 5858 0
14 8046 32838 5852 1024 0 0 1021 5858 0
15 8045 32837 326 1024 0 0 1020 5852 0
16 0012 18 314 1024 0 0 1019 326 0
17 0036 54 316 1024 0 0 1019 326 0
18 0074 116 322 1024 0 0 1019 326 0
19 0020 32 324 1024 0 0 1019 326 0
20 0020 32 328 1024 0 0 1020 5852 326
21 80A3 32931 5854 1024 0 0 1021 5858 5852
22 0036 54 3884 1024 0 0 1020 5854 326
23 0012 18 3890 1024 0 0 1020 5854 326
24 016E 366 3892 1024 0 0 1020 5854 326
25 0020 32 3898 1024 0 0 1020 5854 326
26 0020 32 5856 1024 0 0 1021 5858 5854
27 0020 32 5860 1024 0 0 1022 5880 5858
28 00A5 165 5882 1024 0 0 1023 114 5880
29 00C1 193 5900 1022 14 0 1023 114 5880
$$COLD_FORTH
30 0020 32 5902 1024 0 5884 1023 114 5880
31 80C3 32963 116 1024 0 5884 1024 0 114
32 00A5 165 6354 1024 0 5884 1023 116 5880
33 8083 32899 6372 1022 14 0 1023 116 5880
34 0012 18 3510 1022 14 0 1022 6372 5858
35 004E 78 3512 1022 14 0 1022 6372 5858
36 00EC 236 3518 1020 0 0 1022 6372 5858
37 0096 150 3524 1022 14 0 1022 6372 5858
38 026D 621 3526 1020 0 0 1022 6372 5858
39 0020 32 3528 1024 0 6356 1022 6372 5858
40 0020 32 6374 1024 0 6356 1023 116 6372
41 801A 32794 118 1024 0 6356 1024 0 116
42 002F 47 106 1024 0 6356 1023 118 6372
43 00A5 165 5930 1024 0 6356 1023 118 6372
44 00C1 193 5944 1022 10 1 1023 118 6372
実行終り
45 801B 32795 5946 1024 0 5932 1023 118 6372
46 002F 47 110 1024 0 5932 1022 5946 5858
47 00A5 165 5904 1024 0 5932 1022 5946 5858
48 00C1 193 5926 1022 18 1 1022 5946 5858
実行終り時の処理
49 0020 32 5928 1024 0 5906 1022 5946 5858
50 004E 78 5948 1024 0 5906 1023 118 5946
51 0014 20 5954 1022 0 1 1023 118 5946
例外がスローされました: 'Mind8Kernel.Dispatcher.ExitModule' (mind8dispatch.dll の中)
プログラム '[6176] mind8dispatch.dll' がコード 0 (0x0) で終了しました。
最後が例外スローされていますが、これはmcode=0014の「プロセス終り0」で意図的にスローさせたアプリケーション例外です。
とりあえず終了動作としては意図したものですので、今回のlevel0はいちおう無事に完走したようでした!
お題のC#ソースコード
Dispatcherクラス(C#関数配列)
C#の関数配列
今回実装するのは未実装であったために落ちていたmcode=0x026Dの「ファイルハンドル指定で出力」です。
C版オリジナルでは3ker.cに実装されていますので分割クラスファイルのCsFunctions3kerc.csに実装しました。
using System.Runtime.InteropServices;
namespace Mind8Kernel
{
public partial class Dispatcher
{
/*--------------------- 標準入出力 -----------------------------*/
private void OutputDevice() /* ;WORD ファイルハンドル指定で出力 */
{
/* Mコード=0x026D */
/* (strinfo, filehandle → .) */
// int filehandle;
// size_t length;
// UCHAR *string;
//#define POP_U ((ULONG)(*DstackPointer++))
//#define POP_U_OF_Q (DROP_F,POP_U)
// filehandle = POP_U_OF_Q;
// length = POP_C;
// string = POP_A;
// write( filehandle, string, length ); /* エラーは見ない */
dtp.PopUl();
uint filehandle=dtp.PopUl();
uint length=dtp.PopUl();
uint index=dtp.PopUl();
//保留
}
}
}
実はファイルハンドラを拾ってもそのままCのwrite関数の代替えが思い浮かばなかったため、スタックから拾って実質捨てている仮実装となっています。
SetupCsFunctions内ではC#関数配列のインデックス最大値が変化したので訂正しています。
using System.Text;
using System.Dynamic;
using System.Runtime.InteropServices;
namespace Mind8Kernel
{
public partial class Dispatcher
{
private readonly int maxCountCsFunctions = 1 + 0x026D;
/// <summary>C#の関数配列を準備する</summary>
/// <param name="csFunc">C#関数配列の参照</param>
private void SetupCsFunctions(ref Action[] csFuncs){
//~略~
/*--------------------- 私のプログラム名 -----------------------*/
csFuncs[0x0261]=CmcodeFullFilename;//
/*--------------------- 標準入出力 -----------------------------*/
csFuncs[0x026D]=OutputDevice;//
//~略~
}
}
}
今回追加したのはOutputDeviceだけです。これはいずれ加筆実装します。
つづく
生成されたhello.mcoを解釈して、C#側で「Hello by mind8」が出力されるようにするまでの長い道のりですが、正規版の処理内容に近づくにはまだまだ課題山積です。次回以降でもこのソースコードを肉付けして実際に動く範囲をステップバイステップで広げてまいります。
2024/06/12 追記
C#の関数配列(修正後)
Mind開発者の@killyさんからコメントいただき、mcode=0x026Dの「ファイルハンドル指定で出力」はコンソール出力固定でよいのではとのことでしたので、いったんそのようにさせていただきます。mcode=0x00C1の「$$表示」と同じ実装となります。
using System.Runtime.InteropServices;
using System.Text;
namespace Mind8Kernel
{
public partial class Dispatcher
{
/*--------------------- 標準入出力 -----------------------------*/
private void OutputDevice() /* ;WORD ファイルハンドル指定で出力 */
{
/* Mコード=0x026D */
/* (strinfo, filehandle → .) */
// int filehandle;
// size_t length;
// UCHAR *string;
//#define POP_U ((ULONG)(*DstackPointer++))
//#define POP_U_OF_Q (DROP_F,POP_U)
// filehandle = POP_U_OF_Q;
// length = POP_C;
// string = POP_A;
// write( filehandle, string, length ); /* エラーは見ない */
dtp.PopUl();
uint filehandle=dtp.PopUl();//捨てる
uint length=dtp.PopUl();
uint index=dtp.PopUl();
byte[] chars=mp.GetUb(index,length);
string text = Encoding.GetEncoding("shift_jis").GetString(chars);
Console.Write(text);
}
}
}
お題のMind8の中間コードのC#代替ディスパッチャ実行リスト(修正後)
SqNo mcode mc(dec) mpoint dtp.point dtp+0 dtp+1 rtp.point rtp+0 rtp+1
1 8019 32793 114 1024 0 0 1024 0 0
2 002F 47 102 1024 0 0 1023 114 0
3 0012 18 5862 1024 0 0 1023 114 0
4 0036 54 5864 1024 0 0 1023 114 0
5 0080 128 5870 1024 0 0 1023 114 0
6 0036 54 5872 1024 0 0 1023 114 0
7 0070 112 5878 1024 0 0 1023 114 0
8 803A 32826 5880 1024 0 0 1023 114 0
9 002F 47 238 1024 0 0 1022 5880 0
10 80B8 32952 5858 1024 0 0 1022 5880 0
11 0012 18 5842 1024 0 0 1021 5858 0
12 0036 54 5844 1024 0 0 1021 5858 0
13 0071 113 5850 1024 0 0 1021 5858 0
14 8046 32838 5852 1024 0 0 1021 5858 0
15 8045 32837 326 1024 0 0 1020 5852 0
16 0012 18 314 1024 0 0 1019 326 0
17 0036 54 316 1024 0 0 1019 326 0
18 0074 116 322 1024 0 0 1019 326 0
19 0020 32 324 1024 0 0 1019 326 0
20 0020 32 328 1024 0 0 1020 5852 326
21 80A3 32931 5854 1024 0 0 1021 5858 5852
22 0036 54 3884 1024 0 0 1020 5854 326
23 0012 18 3890 1024 0 0 1020 5854 326
24 016E 366 3892 1024 0 0 1020 5854 326
25 0020 32 3898 1024 0 0 1020 5854 326
26 0020 32 5856 1024 0 0 1021 5858 5854
27 0020 32 5860 1024 0 0 1022 5880 5858
28 00A5 165 5882 1024 0 0 1023 114 5880
29 00C1 193 5900 1022 14 0 1023 114 5880
$$COLD_FORTH
30 0020 32 5902 1024 0 5884 1023 114 5880
31 80C3 32963 116 1024 0 5884 1024 0 114
32 00A5 165 6354 1024 0 5884 1023 116 5880
33 8083 32899 6372 1022 14 0 1023 116 5880
34 0012 18 3510 1022 14 0 1022 6372 5858
35 004E 78 3512 1022 14 0 1022 6372 5858
36 00EC 236 3518 1020 0 0 1022 6372 5858
37 0096 150 3524 1022 14 0 1022 6372 5858
38 026D 621 3526 1020 0 0 1022 6372 5858
Hello by mind8
39 0020 32 3528 1024 0 6356 1022 6372 5858
40 0020 32 6374 1024 0 6356 1023 116 6372
41 801A 32794 118 1024 0 6356 1024 0 116
42 002F 47 106 1024 0 6356 1023 118 6372
43 00A5 165 5930 1024 0 6356 1023 118 6372
44 00C1 193 5944 1022 10 1 1023 118 6372
実行終り
45 801B 32795 5946 1024 0 5932 1023 118 6372
46 002F 47 110 1024 0 5932 1022 5946 5858
47 00A5 165 5904 1024 0 5932 1022 5946 5858
48 00C1 193 5926 1022 18 1 1022 5946 5858
実行終り時の処理
49 0020 32 5928 1024 0 5906 1022 5946 5858
50 004E 78 5948 1024 0 5906 1023 118 5946
51 0014 20 5954 1022 0 1 1023 118 5946
例外がスローされました: 'Mind8Kernel.Dispatcher.ExitModule' (mind8dispatch.dll の中)
プログラム '[1092] mind8dispatch.dll' がコード 0 (0x0) で終了しました。