2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MSX0】MSX0VIBE.PAS【Turbo Pascal】

Last updated at Posted at 2025-12-28

はじめに

Ninune-wa さんの IoT BASIC サンプルを『Turbo Pascal』へ移植してみます。

MSX0VIBE.BAS

BASIC のソースコードは GitHub で公開されています。

項目 説明
概要 内蔵振動モーターを 2 秒間振動させます。
ファイル名 MSX0VIBE.BAS
対応デバイス
コメント Face Bottom Base や Battery Bottoms を装着して、プログラムを実行してください。

See also:

MSX0 Stack での挙動

MSX0VIBE.BAS をロードして、

image.png

実行してみました。

image.png

内蔵振動モーターが 2 秒振動し、その後停止しました。

ただ、当方の環境では連続して実行すると振動モーターが停止しなかったり AXP192 が見つからなくなったりする事がありました。

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

Turbo Pascal へ移植

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

MSX0VIBE.PAS
(* Test Code: MSX0Stack Vibration motor *)
program MSX0VIBE;
type
  LibStr = string[80];
{$I SYSUTILS.LIB}
{$I IOT.LIB}
var
  node: LibStr;
  function FindNode(var node: LibStr; addr: LibStr): Boolean;
  var
    List, Last, p: PItem;
    Flg: Boolean;
  begin
    List := nil;
    Flg := IoTFindCount(node) < 0; { Always False }
    IoTFind(node, List, Last);
    p := List;
    while (p <> nil) and (not Flg) do
      if p^.Data = addr then
      begin
        Flg := True;
        node := node + '/' + p^.Data;
      end
      else
        p := p^.Next;
    ClearListItem(List);
    FindNode := Flg;
  end; { FindNode() }
  procedure Vibe(node: LibStr; Mode: Boolean);
  const
    MStr: array [Boolean] of String[3] = ('OFF', 'ON');
  var
    v: Integer;
  begin
    Writeln('Vibration ', MStr[Mode]);
    IotPutStr(node, #$12); { REG 12H:DC-DC1/3 & LDO2/3 output control }
    v := IotGetInt(node);
    if Mode then 
      v := v or $08   { Vibration ON :REG 12H LDO3 switch cotrol Bit3 (1:enable)  }
    else         
      v := v and $F7; { Vibration OFF:REG 12H LDO3 switch cotrol Bit3 (0:disable) }
    IotPutStr(node, #$12 + Chr(v));
  end; { Vibe() }
  procedure Wait(n: Integer);
  begin
    Writeln('Wait ', n , ' Second');
    Delay(n * 894); { 1sec = 3.579545 / 4 * 1000 }
  end; { Wait() }
begin
  (* Init *)
  ClrScr;
  node := 'device/i2c_i';          { Device Tree }
  if not FindNode(node, '34') then { I2C Address for AXP192 }
  begin
    Writeln('Internal I2C device not found...');
    Exit;
  end;
  (* Vibrator ON *)
  Vibe(node, True);
  (* Wait n Second *)
  Wait(2);
  (* Vibrator OFF *)
  Vibe(node, False);
end.

実行してみました。

image.png

やはり、当方の環境では連続して実行すると振動モーターが停止しなかったり AXP192 が見つからなくなったりする事がありました。うまく動作する時はうまく動作するのですが...。

image.png

解説

サブルーチン

サブルーチンを手続きと関数で書き替えました。コードの総量は増えましたが、読みやすくはなったかもしれません。

結果を利用しない関数

Turbo Pascal 3.0 や標準 Pascal では結果を利用しない関数を呼び出すことができません。例えば Integer 型の結果を返す関数 foo() は、次のような呼び出しはできません。

結果を利用しない呼び出し
  foo(123);

つまり、手続きや関数のパラメータとして使うか、結果を変数に取るしかありません...まぁ、「関数」とは本来そういうものですけれど。

パラメータとして結果を利用
  Bar(foo(123)); 
変数に代入して結果を利用
var
  n: Integer;
begin
  n := foo(123); 
end;  

IoTFind() の前に必ず IoTFindCount() 関数を呼び出す必要があるのですが、この結果は必要ありません。つまり、普通に書くと次のようなコードになります。

var
  Flg: Boolean;
  n: Integer;
begin
  Flg := False;
  n := IoTFindCount(node);
  ...
  • Flg は False で初期化したい
  • IoTFindCount() は常に実行したい
  • IoTFindCount() が返す結果は利用しない

この条件を満たすように短く書くと、次のようなコードになる訳です。

var
  Flg: Boolean;
begin
  Flg := IoTFindCount(node) < 0; // IoTFindCount() は負数を返さないため、常に False
  ...

短くできましたが、初見では何をやっているのか理解できないかもしれませんね。あまりいいコードではないです。

なお、結果を無視して関数を実行できる拡張構文 {$X+} は Turbo Pascal 6.0 以降で利用可能です。

おわりに

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

See also:

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?