【MSX0】LED.PAS【Turbo Pascal】

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

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

# LED.BAS
◆MSX0 Stack 情報表示

| 項目 | 説明 |
|:---|:---|
| 概要 |Face Bottom Base や Battery Bottoms に搭載されている 10 個の LED を iotput 命令を使って制御します。 |
| ファイル名 | LED.BAS |
| 対応デバイス |  |
| コメント | Face Bottom Base や Battery Bottoms を装着して、プログラムを実行してください。 |

**See also:**

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

## MSX0 Stack での挙動

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/3e214332-55b5-c651-9bdc-ed801091e68d.png)

実行してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/4273d0b5-3e01-35d6-e20c-0e2552445c7c.png)

あら真っ黒...なんですけど、LED が RGB / 回転 / フラッシュを繰り返します。

:::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:LED.PAS
program LED;
{$I MDLLIB.LIB}
{$I VRAM1.LIB}
{$I SYSUTILS.LIB}
{$I IOT.LIB}
var
  I, L, P: Byte;
  W, WN: Integer;
  D: LibStr;
  PT: array [0..9] of LibStr;

  procedure AllSame(R, G, B: Byte);
  begin
    D := Chr(G shl 4 + B) + Chr(10 shl 4 + R);
    IoTPutStr('device/leds/data', D);
    sys_timer := 0;
    repeat
    until sys_timer >= 60;
  end; { AllSame }

  procedure AllOff;
  begin
    IoTPutInt('device/leds/trans_ms', 300);
    AllSame(0, 0, 0);
  end; { All Off }

  procedure LEDColor(R, G, B: Byte);
  begin
    for P := 0 to 9 do
    begin
      D := '';
      for I := 0 to 9 do
        if I = P then
          D := D + Chr(G shl 4 + B) + Chr(R)
        else
          D := D + #$00#$00;
      PT[P] := D;
    end;
  end; { LEDColor }

  procedure RGB;
  begin
    IoTPutInt('device/leds/trans_ms', 1000);
    for L:=1 to 3 do
    begin
      AllSame(15, 0, 0);
      ALLSame(0, 15, 0);
      ALLSame(0, 0, 15);
    end;
  end; { RGB }

  procedure Rotate;
  begin
    LEDColor(0, 0, 15); (* Blue *)
    IoTPutInt('device/leds/trans_ms', 100);
    for L := 1 to 50 do
    begin
      WN := 30 - L;
      if WN < 0 then WN := 0;
      for I := 0 to 9 do
      begin
        IoTPutStr('device/leds/data', PT[i]);
        for W := 0 to WN do Delay(1);
      end;
    end;
    AllOff;
  end; { Rotate }

  procedure Flash;
  begin
    LEDColor(15, 15, 15); (* White *)
    IoTPutInt('device/leds/trans_ms', 20);
    for L := 1 to 200 do
      IoTPutStr('device/leds/data', PT[Random(10)]);
    AllOff;
  end; { Flash }
begin
  ClrScr;
  Color(15, 1, 1);
  repeat
    RGB;
    Rotate;
    Flash;
  until KeyPressed;
  AllOff;
  Color(15, 4, 7);
end.
```

実行してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/4273d0b5-3e01-35d6-e20c-0e2552445c7c.png)

いや、画面は真っ黒なんですけどね (^^;A

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/7b7485bd-b36f-f271-c256-084c8868b797.png)

ちゃんと光ります。

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

### 解説

#### サブルーチン
サブルーチンは手続きに変更してあります。お行儀が悪いですが、コードの行数を減らすためにループ変数等をグローバル変数として宣言してあります。

#### TIME システム変数 (BASIC)
BASIC の TIME システム変数は ワークエリア FC9E (JIFFY) と同じです。`MDLLIB.LIB` では `sys_timer` として定義されています。 

**See also:**

 - [Appendix A.2 ワークエリア (MSX Datapack wiki化計画)](http://ngs.no.coocan.jp/doc/wiki.cgi/datapack?page=Appendix+A%2E2+%A5%EF%A1%BC%A5%AF%A5%A8%A5%EA%A5%A2)

#### 前景色 / 背景色 / 境界色
終了時にデフォルトカラーに戻すようにしました。

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

:::note
LED を制御するにはファームウエア ver0.07.08 以上が必要です。
:::