【MSX0】PERFORMC.PAS【Turbo Pascal】

# はじめに
『MSX0 Stack』付属の IoT BASIC サンプルを『Turbo Pascal』へ移植してみます。

 - [【MSX0】IoT BASIC サンプルの移植【Turbo Pascal】(Qiita)](https://qiita.com/ht_deko/items/2362488c5c99aec4afbf)

# PERFORMC.BAS
◆負荷測定

| 項目 | 説明 |
|:---|:---|
| 概要 |仮想 Z80 の周波数を振ってオーバークロック余力を測定します。 |
| ファイル名 | PERFORMC.BAS |
| 対応デバイス |  |
| コメント | SCREEN モードや、ネットワーク機能利用時など使用状況に影響を受けます。 |

**See also:**

 - [『MSX0 Stack』の操作方法 - ハードウェア (Qiita)](https://qiita.com/ht_deko/items/cdb1594e9879a5e9e660)

## MSX0 Stack での挙動

`PERFORMC.BAS` をロードして、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/1847a954-af23-eea9-5ecf-f9ad776b9c41.png)

実行してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/6e254b15-5088-c2bd-c824-d71a8c4c2099.png)

240% までクロックアップしながら負荷測定を行います。`OVER` が表示され負荷が 100% を超えると処理が追い付いていない事を意味します。逆に言うと、負荷が 100% を超えない範囲ならクロックアップが可能という事になります。

:::note info
プログラムは〔Ctrl〕+〔Stop〕(リモートコントロールパネルからは〔Ctrl〕+〔F12〕) で中断できます。
:::

## Turbo Pascal へ移植

別途、MDL-LIB と `SYSUTILS.LIB`、`IOT.LIB` が必要です。

 - [MDL-LIB version 2.2 の使い方 (Qiita)](https://qiita.com/ht_deko/items/6f15aee0bd25b550e4df)
 - [【MSX0】IOT.LIB (Qiita)](https://qiita.com/ht_deko/items/a5c0bf6e7969093beb3c)

```pascal:INFO.PAS
program PERFORMC;
{$I MDLLIB.LIB}
{$I VRAM2.LIB}
{$I SYSUTILS.LIB}
{$I IOT.LIB}
label
  JP;
type
  Str4 = string[4];
const
  OVSTR: array [Boolean] of Str4 = ('', 'OVER');
var
  S: Byte;
  I, P, W: Integer;
begin
  S := sys_scrmod;
  ScrMode(1);
  Writeln;
  Writeln('**** PERFORMANCE CHECK ****');
  Writeln;
  I := 0;
  repeat
    I := I + 20;
    IoTPutInt('msx/me/pm/cpu/percent', I);
    write('Z80:', I:3, '% ');
    for W:=0 to 2 do
    begin
      Delay(I * 10);
      if KeyPressed then
        goto JP;
      write('-');
    end;
    P := IoTGetInt('msx/me/pm/cpu/load');
    Writeln(' LOAD:', P:3, '% ', OVSTR[P > 100]);
  until I >= 280;
  Writeln;
  Writeln('Press any key.');
  while not KeyPressed do
    ;
JP:
  IoTPutInt('msx/me/pm/cpu/percent', 100);
  ScrMode(S);
end.
```

実行してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/19cf316e-5b64-7f69-53ae-167bc758507b.png)

`SAMPLE.TXT` の説明にもあったように負荷は環境によって左右されるようで、BASIC での結果よりも負荷が軽めに出るようです。

:::note info
任意のキーで中断できます。
:::

### 解説

#### ループ (1)
Pascal の **for** 文にステップ構文はないので、`I` のループは **repeat** ～ **until** で置換しています。 

 - [4.4.3. for to do 文 (For statement) (Qiita)](https://qiita.com/ht_deko/items/05af01a81f7c3bb5eeb4#443-for-to-do-%E6%96%87-for-statement)

#### ループ (2)
多重ループを抜けるために **goto** を使っています。Pascal に行番号はないのでラベルによるジャンプとなります。

 - [Delphi で多重ループを抜ける方法 (Qiita)](https://qiita.com/ht_deko/items/ec4963f6d6ade3db8734)

#### 負荷
負荷が軽めなので、280% まで測定する事にしました。

#### 測定終了時の処理
プログラム終了時にスクリーンモードを元へ戻すようにしましたが、そうすると測定終了後の画面を確認できないため、何かのキーが押されるまで画面をそのままにしておく事にしました。

# おわりに
今回の移植に関して難しい所は特にありませんでした。

記事に関連しますが、以前 MSX-DOS でクロックアップを行うトランジェントコマンド **M0CLKUP** を作った事があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/a9097df1-7a60-f1bb-b223-99e1603918ff.png)

 - [M0CLKUP - 【MSX0】IOT.LIB (Qiita)](https://qiita.com/ht_deko/items/a5c0bf6e7969093beb3c#-m0clkup)

MSX-C のセルフコンパイルは遅いので、M0CLKUP で 200% にクロックアップしてコンパイルし、実行形式ファイルは 100% に戻して実行する、なんて事が可能です。

 - [MSX0 Stack で MSX-C ver1.2 のディスクを作る (C コンパイラを動かせるようにする) (Qiita)](https://qiita.com/ht_deko/items/c81fdf6a9758cbf824ac)

事前にパフォーマンスチェックを行って、何 % くらいまでクロックアップが可能なのかを調べておくといいかもですね。