MS-DOS ver2.0 と MSX-DOS のバッチコマンド

# はじめに

MSX-DOS / MSX-DOS2 / COMMAND 2.44 でバッチファイル内で使えるコマンドが判りづらかったので、MS-DOS ver2.0 と比較してみる事にしました。

:::note
MSX-DOS の `COMMAND.COM` および、MSX-DOS2 の `COMMAND2.COM` は MS-DOS の `COMMAND.COM` を MSX へ移植したものです (サブセット)。
:::

## COMMAND.COM / COMMAND2.COM のバージョン

バージョンです。

| 名称 | バージョン | 入手先 |
|:---|:---:|:---|
| COMMAND.COM | 1.11 | ・MSX-DOS Tools<br>・MSX･FAN 1991/11～ |
| COMMAND2.COM | 2.20 | ・MSX-DOS2 のシステムディスク |
| COMMAND2.COM | 2.30 | ・FS-A1ST (turboR) MSX-DOS2<br>・MSX･FAN 1992/06～<br>・MSX Magazine 永久保存版 2 |
| COMMAND2.COM | 2.31 | ・FS-A1GT (turboR) MSX-DOS2<br>・MSX･FAN 1992/08～<br>・MSX Magazine 永久保存版 3 |
| COMMAND2.COM | 2.44 | ・[The New Image (TNI)](http://www.tni.nl/products/command2.html) |

:::note
MSX-DOS2 の「カーネル」「MSXDOS2.SYS」「COMMAND2.COM」のバージョンは異なっていても利用可能です。
:::

:::note warn
MSX-DOS2 から MSX-DOS1 でフォーマットされたディスクのプログラムを実行しようとすると `Wrong version of MSX-DOS` のエラーが出ます。これを回避するには 環境変数 **EXPERT** を `ON` に設定します。
:::

**See also:**

 - [COMMAND2.COM ver2.44 の入手方法 - 『MSX0 Stack』の操作方法 - ソフトウェア (Qiita)](https://qiita.com/ht_deko/items/8c20354b867b0d540805#command2com-ver244-%E3%81%AE%E5%85%A5%E6%89%8B%E6%96%B9%E6%B3%95)

# バッチコマンド
MS-DOS 2.0 時点のバッチコマンドは 7 つあります。

```
ECHO, FOR, GOTO, IF, PAUSE, REM, SHIFT
```

## ECHO

メッセージを表示したり、コマンドエコーの ON と OFF を切り替えます。

|MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | △ | ○ | ○ |


```txt:書式1
ECHO [ON | OFF]
```

`ECHO ON` に設定すると、バッチファイル実行中にそのバッチファイル中のコマンドの実行状態をスクリーンに表示 (エコーバック) します。

```txt:書式2
ECHO <文字列>
```

`書式2` は文字列をスクリーンに表示します。

次の例は、`Hello,world.` を表示します。

```batch:例
echo Hello,world.
```

 - MSX-DOS / MSX-DOS2 は `書式1` に対応していません
 - MSX-DOS の ECHO は外部コマンド `ECHO.COM` です。『MSX-DOS TOOLS』に含まれています
 - ECHO のみを実行すると、MS-DOS ではエコーバックの状態を表示しますが、MSX-DOS / MSX-DOS2 では空行を表示します


## FOR
指定されたコマンドを集合の各値に対して実行します。

|MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | × | × | × |

```txt: 書式
FOR %%<変数> IN (<集合>) DO <コマンド> [コマンドパラメータ]
```

集合の値を一つずつ取り出して変数に格納します。変数はコマンドやコマンドパラメータで使う事ができます。

次の例は、`*.BAK` と `*.TMP` にマッチするファイルを削除します。

```batch:例
for %%F in (BAK TMP) do del *.%%F
```

 - コマンドラインで使う場合には `%%<変数>` の部分は `%<変数>` になります


## GOTO

ラベル行へジャンプします。

| MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | × | × | △ |


```txt: 書式
GOTO :<ラベル>
```

次の例は、`world.` だけを表示します。

```batch:例
goto :JP
echo Hello,
:JP
echo world.
```

 - ラベルの先頭には `:` (コロン) を指定し、ラベルだけを単独で 1 行に入力します
 - COMMAND 2.44 の場合: **GOTO** をバッチファイル内で使うには、拡張子を `*.BTM` に変更する必要があります
 - COMMAND 2.44 の場合: ラベルは `:` (コロン) ではなく `~` (チルダ) で始まります
 - COMMAND 2.44 の場合: `*.BTM` の実行に<font color="crimson">マッパー RAM の空きが 16KB 以上必要</font>です
 - COMMAND 2.44 の場合: BTM 形式のバッチファイルでは、**GOTO** の他に **GOSUB**, **RETURN**, **END** が使えます。 


## IF

バッチプログラム中で条件分岐を行います。

|MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | × | △ | ○ |


```txt: 書式1
IF [NOT] ERRORLEVEL <数値> コマンド
```
```txt: 書式2
IF [NOT] <文字列1>==<文字列2> コマンド
```
```txt: 書式3
IF [NOT] EXIST <ファイル名> コマンド
```

次の例は、バッチファイルが `fast` パラメータ付きで実行された場合に `M0CLKUP 200` を実行します。

```batch:例
if %1==fast M0CLKUP 200
```

 - MSX-DOS2 は `COMMAND2.COM ver2.31` において **IF** に対応しています
 - 空文字列は `""` です
 - COMMAND 2.44 は `書式1` に対応していません
 - COMMAND 2.44 は比較演算子として `==` の他に `EQ` (=), `LT` (\<), `GT` (\>) が使えます。NOT と組み合わせる事により、柔軟な比較演算を行えます

:::note
COMMAND 2.44 では変数をダブルクォーテーションで括ると、MS-DOS / COMMAND.COM 2.31 とは異なり文字列とみなす (`" + 展開された変数 + "` とはならない) ので `"%1"=="ABC"` のような書き方はできません。

しかしながら `%1==文字列` のような書き方だと、バッチファイルにパラメータが渡されなかった時に `==文字列` という式になってしまい、<font color="crimson">Invalid Parameter</font> のエラーになってしまいます。

```batch:例
if fast==%1 M0CLKUP 200
```

この問題を回避するには、変数を右辺に置きます。また、COMMAND 2.44 ではダブルクォーテーションの代わりに中括弧が使えるため、こちらで回避する事もできます。

```batch:例
if {%1}=={fast} M0CLKUP 200
```
:::

## (IFF)

COMMAND 2.44 では複数行 **IF** である **IFF** が使えます。

|MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| × | × | × | ○ |

```txt: 書式1
IFF [NOT] EXIST <ファイル名> [THEN] [<コマンド>]
    .
    .
ENDIFF [<コマンド>]
```

```txt: 書式2
IFF [NOT] <文字列1> ==|EQ|LT|GT <文字列2> [AND|OR|XOR [NOT]
          <文字列3> ==|EQ|LT|GT <文字列4> [AND|OR|XOR ...]] [THEN]
  <コマンド>
    .
    .
ENDIFF [<コマンド>]
```

:::note
詳細は COMMAND 2.44 のドキュメントを確認してください。
:::

## PAUSE

バッチ処理を一時停止します。

|MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | ○ | ○ | ○ |

```txt: 書式
PAUSE [<文字列>]
```

```batch:例
pause 
```

 - MSX-DOS では `文字列` を指定できません

## REM

コメントを記述します。

| MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | × | ○ | ○ |

次の例は、バッチファイルにコメントを記述します。

```txt: 書式
REM [文字列]
```

```batch:例
rem --------------------
rem  TEST
rem --------------------
```

 - MS-DOS では `:` がラベル行である事を利用して `: TEST` のようなコメント行が記述可能です
 - MS-DOS2 / COMMAND 2.44 では **GOTO** が使えないにもかかわらず `: TEST` のようなコメント行が記述可能です

## SHIFT

バッチファイル中のパラメータの位置を変更します。

| MS-DOS 2.0 | MSX-DOS | MSX-DOS2 | COMMAND 2.44 |
|:---:|:---:|:---:|:---:|
| ○ | × | × | ○ |

**SHIFT** を実行すると、バッチファイルに渡されたパラメータの位置が一つ前へ (左へ) ずれます。

```txt: 書式
SHIFT
```

次のバッチファイルを `ABC DEF` というパラメータ付きで実行すると、

```batch:例
echo %1
shift
echo %1
```

次のような結果になります。

```batch:結果
ABC
DEF
```


# おわりに

MSX-DOS / MSX-DOS2 のマニュアルにバッチファイルの書き方って載ってましたっけ？ 

 - [MSX-DOS Manual (アカシックライブラリ)](https://akasik-libraries.jp/modules/booklist/bookinfo.php?id=566)
 - [MSX-DOS2 ユーザーズガイド (アカシックライブラリ)](https://akasik-libraries.jp/modules/booklist/bookinfo.php?id=569)
 - [MSX-DOS2 リファレンスマニュアル (アカシックライブラリ)](https://akasik-libraries.jp/modules/booklist/bookinfo.php?id=583)

MS-DOS ver2.0 の詳しい情報は『標準 MS-DOS ハンドブック』に載っています。

:::note
[『標準 MS-DOS ハンドブック』](https://dl.ndl.go.jp/pid/12630935)は国立国会図書館デジタルコレクションで読む事ができます。書籍の閲覧には国立国会図書館の利用者登録 ([本登録](https://www.ndl.go.jp/jp/registration/individuals_official.html)) が必要です。
:::