since 2007.8 by K-ichi

先日はMAX IIでPWMを構成し、LEDをSIN波ドライブしたが、あのハードウェアが必須というわけではない。MSX本体だけで見られるよう、内蔵のLED(CAPS)を同様に光らせてみた。

後に示す10行足らずのBASICプログラムを使う。速度的にBASICオンリーではさすがに無理なので、PWMの部分のみマシン語で動作させている。多少点滅して見えるのは、BASICでサインなどの計算しているため。すべてマシン語で書けば、ハードウェアで作られたものと見分けがつかないレベルにすることは可能。


行110の、D$に入れられる文字列がマシン語そのもの。文字列領域に保存される。行120-130で実行アドレスを設定。行140以降が点灯ループ。
行150は、サインの計算結果をマシン語ルーチンに与えるとともに、MAX IIのI/Oにも渡している。例のハードウェアがあれば、そちらも一緒に動く。USR関数へ渡す値を¥1しているのは、整数型で渡す必要があるため。
行170でキー入力を調べ、何も入力がなければ点灯を繰り返す。行180では、CAPSの状態をシステムワークエリアから得て、LEDを適正な状態に戻す。

BASICのリストは以下の通り。なお、ここで全角で表している部分は、実際はすべて半角。

100 'save"PWM.bas",a
110 D$="も##> ゆなfッえo( >,モォ% ん>-モォe% んちむ= とろノ@@@@@@@@@@(な"
120 A=VARPTR(D$)+1
130 DEF USR=PEEK(A)+PEEK(A+1)*256
140 FOR I=0 TO ATN(1)*4*2 STEP .1
150 OUT 0,USR(((SIN(I)*.5+.5)^2*256)¥1)
160 NEXT
170 A$=INKEY$:IF A$="" THEN 140
180 OUT &HAB,-(PEEK(&HFCAB)=0)+6*2

MSX_PWM.zip ……BASICおよびマシン語のソース


MSXturboRの高速モードで、例の起動動作の半分程度の速度。Z80モード(およびMSX2+以前の機種)では、SIN計算に時間がかかり、ただの点滅に見えてしまう。Z80でそれっぽく見せるには、DEFINT A-Zですべて整数扱いを宣言し、配列変数に予めSIN計算結果を入れておき、それを参照するように変更。これでかなり近い動作になる。
ちなみに、ATN(1)*4*2は2πのことで、STEP .1なので、62個の配列に計算しておけば同じ精度になる。

0 件のコメント:

コメントを投稿

.

関連記事


この記事へのリンク by 関連記事、被リンク記事をリストアップする」記事

ブログ アーカイブ