【MSX0】BLINK.PAS【Turbo Pascal】

# はじめに
Seeed 社の [『Grove Beginner Kit for Arduino』](https://www.seeedstudio.com/Grove-Beginner-Kit-for-Arduino-p-4549.html) のセンサーのうち、MSX0 の IoT BASIC のサンプルがないものを『Turbo Pascal』で動作させてみます。

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

# BLINK
LED [D4] を点滅させます。いわゆる **L チカ**です。

## MSX0 Stack での挙動

まず事前にモジュールをつないでおきます。MSX0 側は **Port B** (黒) に接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/205fb13d-848b-4511-1546-c432eaa1c7e7.png)

| センサー | 接続方法 | Grove ポート |
|:---|:---|:---|
| [D4] LED | Digital | Port B (黒色) |

左上のモジュールが LED です。黄色の部品は半固定抵抗で、LED の輝度を調整するものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/fe301107-1f7d-c9cb-b85a-588b5f5fdc2a.png)

## GROVE ケーブルの修正 (クロスケーブルの作成)

MSX0 で L チカをするためには、GROVE ケーブルの黄色と白の線を入れ替える必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b08b1803-8d99-bcc5-4b8a-5bda0f810040.png)

マイナスの精密ドライバー (100 均で買えます) でコネクタのツメを持ち上げながら線を引っ張ると、ピンを抜く事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/29524062-0c63-71ef-20f0-d46776cc72d3.png)

Grove ケーブルの片方のコネクタの黄色と白の線を入れ替えてください。奥までカチっと差し込んで、線を軽く引っ張って抜けなければ OK です。ツメを持ち上げすぎるとコネクタが破損しますので注意してください。

| ピン | ケーブル | モジュール | Port B |
|:---:|:---:|:---:|:---:|
| 1 | 黄 | SIG | I |
| 2 | 白 | NC | O |
| 3 | 赤 | VCC | V |
| 4 | 黒 | GND | G |

モジュールの LED は Pin1 (外側: 黄色) に接続されていますが、MSX0 Stack Port B の出力ピンは Pin2 (内側: 白色) となっているため、線を入れ替える必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/d90b0973-5ab3-6f83-076b-768594a89039.png)

付属の Grove ケーブルを 1, 2 本、クロス接続にしておくとよいでしょう。コネクタを任意の色のマーカーペンで着色しておくと誤接続防止になります。

**See also:**

 - [『MSX0 Stack』の操作方法 - ハードウェア](https://qiita.com/ht_deko/items/cdb1594e9879a5e9e660#grove-%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF)

## MSX-BASIC のコード

MSX-BASIC での Lチカについては HRA! さんの資料 (6.3. L チカ) を参考にしてください。

 - [MSX0入門 (Github: @hra1129)](https://github.com/msx-sample-code-space/for_msx0/blob/main/information/development/HRA!/MSX0%E5%85%A5%E9%96%80.pdf)


## Turbo Pascal のコード

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

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

```pascal:BLINK.PAS
program BLINK;
type
  LibStr = string[80];
{$I SYSUTILS.LIB}
{$I IOT.LIB}
begin
  while not KeyPressed do
  begin
    IoTPutInt('device/analog/out', 4095);
    Delay(894);
    IoTPutInt('device/analog/out', 0);
    Delay(894);
  end;
end.
```

実行すると LED が 1 秒おきに点灯と消灯を繰り返します。

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

### 解説

#### IoTPutInt()
普通、L チカと言ったら Digital ピンで ON / OFF するものですが、MSX0 にはデジタル入出力用の IoT ノードが用意されていないので、アナログ出力用の IoT ノード (`device/analog/out`) で代用します。MSX0 の仕様によるとアナログ出力は 12bit なので、0..4095 の値をとります。ON (4095) / OFF (0) を繰り返し行う事で LED を点滅させます。

#### Delay()
本来は 1000 で 1 秒なのですが、Turbo Pascal の TINST では動作周波数を整数でしか入力できないので、4 MHz にするのが MSX の動作周波数 3.579545 MHz に最も近くなります。

LED を 1 秒おきで点灯 / 消灯するには、この誤差を修正する必要があります。Delay() の引数である `894` という値は **3.579545 / 4 * 1000** から来ています。1 カウントは 1/1000 秒 (1 ミリ秒) です。

**See also:**

 - [Turbo Pascal 3.0 のスクリーン設定 (Qiita)](https://qiita.com/ht_deko/items/0d8976801c02ec685bd6#msx-dos-%E7%94%A8%E3%81%AE%E8%A8%AD%E5%AE%9A)


## Turbo Pascal のコード (その２)
もう一つ L チカのプログラムです。別途、`MDLLIB.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:BLINK2.PAS
program BLINK2;
{$I MDLLIB.LIB}
{$I SYSUTILS.LIB}
{$I IOT.LIB}
begin
  while not KeyPressed do
  begin
    sys_timer := 0;
    IoTPutInt('device/analog/out', 4095);
    while sys_timer < 60 do
      ;
    sys_timer := 0;
    IoTPutInt('device/analog/out', 0);
    while sys_timer < 60 do
      ;
  end;
end.
```

### 解説

#### sys_timer
MSX のタイマーを使って 1 秒を測定しています。sys_timer はワークエリアの FC9E (JIFFY) です。使い方は BASIC の TIME システム変数と同じで、1 カウントは 1/60 秒です。

# おわりに
L チカは難しくありませんね。