Pascal/MT+ の簡単な使い方

# はじめに
Digital Research 社の Pascal/MT+ の使い方についての備忘録です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/03cbf418-a392-6a40-4291-f43546473d38.png)
CP/M エミュレータとして **RunCPM** の Win32 バイナリを使います。

 - [RunCPM (Github)](https://github.com/MockbaTheBorg/RunCPM/)
 - [RunCPM v3.7 Win32 バイナリ (Github)](https://github.com/MockbaTheBorg/RunCPM/blob/bc0a1b35b5598fdf95c7559b48dbdfdcaff9a92f/Release/RunCPM.exe)

Pascal/MT+ は次のリンクから入手できます。

 - [Pascal/MT+ (Wikipedia: en)](https://en.wikipedia.org/wiki/Pascal/MT%2B)
 - [Pascal/MT+ Binaries for CP/M](http://www.cpm.z80.de/binary.html#languages)

**See also:**

 - [RunCPM (Z80 CP/M 2.2 エミュレータ) (ht-deko.com)](https://ht-deko.com/arduino/runcpm.html)
 - [付録 (標準 Pascal 範囲内での Delphi 入門) (Qiita)](https://qiita.com/ht_deko/items/15b27e00fac9d723d9f0)
 - [用語集 (標準 Pascal 範囲内での Delphi 入門) (Qiita)](https://qiita.com/ht_deko/items/56e4910d7e00d9bcc5b2)

# Pascal/MT+ の使い方

とりあえず `FIZZBUZZ.PAS` を用意しておきます。

```pascal:FIZZBUZZ.PAS
program FizzBuzz(Output);
var
  i: Integer;
begin
  for i:=1 to 100 do
    begin
      if ((i mod 3) + (i mod 5)) = 0 then
        Writeln('Fizz Buzz')
      else if (i mod 3) = 0 then
        Writeln('Fizz')
      else if (i mod 5) = 0 then
        Writeln('Buzz')
      else
        Writeln(i);
    end;
end.
```


## ■ コンパイル
コンパイラは `MTPLUS.COM` です。ソースファイルの拡張子は省略できます。

```:USAGE
MTPLUS <ファイル> {<オプション>}
```

```:Example
MTPLUS FIZZBUZZ
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/4712384e-08cd-9676-545c-a8242741cea8.png)
これで `FIZZBUZZ.ERL` ファイルが生成されます。

## ■ リンク
リンカは `LINKMT.COM` です。

```:USAGE
LINKMT <メインモジュール>{,<モジュール>}{,<ライブラリ>} {<オプション>}

または

LINKMT <実行ファイル名>=<メインモジュール>{,<モジュール>}{,<ライブラリ>} {<オプション>}
```

```:Example
LINKMT FIZZBUZZ,PASLIB /S
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ab1a07a3-6ed5-5b5e-8c5f-c777f6c77c9f.png)
正しくリンクされると `FIZZBUZZ.COM` が生成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/18132141-49e3-e168-6d91-21a0d28ca7f1.png)


## ■ コンパイル＆リンク

`A` オプションをコンパイラに渡す事により、自動的にリンカを呼び出せます。

```:Example
MTPLUS FIZZBUZZ $A
```

しかしながら、自動でリンクするためには `リンカ入力コマンドファイル` が別途必要です (拡張子 `.CMD`)。

```:FIZZBUZZ.CMD
FIZZBUZZ,PASLIB /S
```

この仕様だとあまり有用だとは思えませんね。

# おわりに

**Pascal/MT+** と **標準 Pascal** との (標準 Pascal の範囲での) 違いは次の通りです:

 - 識別子は最初の 8 文字のみが有効。
 - 変数はビットレベルでは PACK されていない。
 - 宣言の順番が異なる場合がある。
 - ヌル文字列を許容する。
 - 可変長文字列 (**String**) をサポートしているため、**CHAR** は ISO Pascal 文字列 (**PACKED ARRAY** [1...n] **OF CHAR**) として実装されていない。

他にも、追加の機能として I/O 操作があったり、モジュール構造が取り入れられたりしています。

## モジュール

実際のモジュールの使い方についてですが、モジュールファイルはこのようになります。

```pascal:FBMOD.PAS
module FBMOD;

procedure FB;
var
  i: Integer;
begin
  for i:=1 to 100 do
    begin
      if ((i mod 3) + (i mod 5)) = 0 then
        Writeln('Fizz Buzz')
      else if (i mod 3) = 0 then
        Writeln('Fizz')
      else if (i mod 5) = 0 then
        Writeln('Buzz')
      else
        Writeln(i);
    end;
end;

modend.
```

モジュールのルーチンを呼び出す側のメインプログラムはこうなります。

```pascal:FIZZBUZZ.PAS
program FizzBuzz(Output);

EXTERNAL PROCEDURE FB;

begin
  FB;
end.
```

まずはそれぞれのモジュールをコンパイルし、

```
MTPLUS FBMOD
MTPLUS FIZZBUZZ
```

リンカで結合します。

```
LINKMT FIZZBUZZ,FBMOD,PASLIB /S
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/91beffb4-bbec-baff-2883-124e536f472a.png)