5
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?

DelphiAdvent Calendar 2023

Day 16

【MSX0】ANALOG_G.PAS【Turbo Pascal】

Last updated at Posted at 2023-12-16

はじめに

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

ANALOG_G.BAS

◆アナログ入力

項目 説明
概要 Port B (黒) のピン 36 からのアナログ入力信号で簡単なグラフを描きます。
ファイル名 ANALOG_G.BAS
対応デバイス Seeed Grove [A0] Rotary Potentionmeter
Seeed Grove [A6] Light
Seeed Grove [A2] Sound
Seeed Grove [D6] Button
その他自作の機器
コメント ※[A6]太陽光など比較的強い光でないと反応しないようです。
※[D6]本来はデジタル入力です

このサンプルを動作させるには外部センサーが必要です。

See also:

MSX0 Stack での挙動

ANALOG_G.BAS をロードして、

image.png

実行してみました。

image.png

MSX0 側の黒い Port B とセンサーの Grove コネクタをケーブルで接続します。

image.png

センサー 操作
[A0] Rotary Potentionmeter ツマミを回す
[A6] Light 強い光 (日光やスマホのフラッシュライト) をあてる
[A2] Sound 「ハドソン!」と叫んでみる 息を吹きかける
[D6] Button ボタンを押してみる

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

Turbo Pascal へ移植

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

ANALOG_G.PAS
program ANALOG_G;
{$I MDLLIB.LIB}
{$I VRAM2.LIB}
{$I GRAPMSX2.LIB}
{$I SYSUTILS.LIB}
{$I IOT.LIB}
var
  A, X, Y: Integer;
begin
  ScrMode(5);
  while not KeyPressed do
  begin
    A := IoTGetInt('device/analog/in');
    Y := 206 - Trunc(A / 4096 * 200);
    if X = 0 then
      Plot(X, Y, 15) 
    else 
      DrawTo(X, Y, 15);
    X := X + 1;
    if X >= 256 then 
    begin
      X := 0;
      ClrScr;
    end;  
  end;
  TextMode;
end.

実行してみました。

image.png

BASIC の時同様、各種センサーで値が変動します。

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

解説

アナログ入力の解像度は 12bit (0..4095) です。

Y 軸の求め方

Y 軸の計算は実数型 (Real) で行いました。オリジナル (BASIC) の式は次のようになっています。

40 Y=206-A/4096*200

これを Pascal に置き換えるわけですが、次の式だと整数除算なので、4096 で割っている箇所で値は 0 になってしまいます。

 Y := 206 - A div 4096 * 200;

式を変形して次のようにやってしまうと、式の途中で MAXINT の範囲 (-32768..32767) を超えてしまいます。Turbo Pascal 3.0 の整数型には Integer (Int16) しかないのです。

 Y := 206 - A * 200 div 4096;

Trunc() で括れば、その部分だけを実数演算できます。Turbo Pascal 3.0 の実数型は 48bit なので、計算結果が範囲を超える事はありません。

Y := 206 - Trunc(A / 4096 * 200);

変数 Y を最初から実数型で宣言してもいいのですが、スクリーン座標は整数なので整数型で宣言したかったのです。

スクリーンモード

MSX-DOS 自身はテキストモードである SCREEN 1 or 0 で実行されています。

テキスト画面の桁数を指定する MSX-DOS の内部コマンド MODE n で n に 32 以下の数字を設定すると SCREEN 1、それよりも大きな数を指定すると SCREEN 0 で動作します。

プログラムは実行時にグラフィックモードの SCREEN 5 (256x212 / 1 ドットごとにパレットからの 1 色) に移行しているので、プログラム終了時に TextMode() を使って、プログラム実行前のテキストモードに戻しています。こうしないと Turbo Pascal や MSX-DOS へ戻った時にバグってしまうようです。

MDLLIB で、MSX2 以降用のライブラリ (VRAM2.LIB および GRAPHMSX2.LIB) をリンクしていますが、これは SCREEN 5 が MSX2 以降で使えるスクリーンモードだからです。

おわりに

今回の移植もあまり難しい所はありませんでしたね。

5
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
5
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?