HELP Contents

1 PMLエミュレータ使用ガイド

2 エミュレータの機能

3 PML言語リファレンス

4 外部入出力機器リファレンス

5 高度な機能

6 汎用ルーチンリファレンス

6.1 サブルーチン

6.1.1 サブルーチンの概要

6.1.2 マルチワード演算について

6.1.3 文字列について

6.2 GENERAL:条件判断マクロ

6.2.1 変数の値のチェックする

6.2.2 直前の計算結果のチェック

6.2.3 二つの値の比較

6.3 GENERAL:ウェイト

6.4 CALC:整数演算

6.4.1 1ワード乗除算

6.4.2 マルチワード演算

6.4.3 その他のルーチン

6.5 STRINGS:文字列処理

6.5.1 文字列処理

6.5.2 モニタ操作

Top Menu

6 汎用ルーチンリファレンス

この章ではサンプルプログラムを作るために作ってしまった汎用に使えそうなマクロおよびサブルーチンの解説をします。

6.1 サブルーチン

Page Top

このサブルーチン集は前にも述べたとおり、新装版を出すにあたってサンプルプログラムを追加しようと思ったところかけ算割り算が必要になって、さらにマップ上に歩数を表示するのに文字列処理などが必要になって、さらに疑似乱数を作っていたら1ワードの数では満足いく乱数がでなかったので結局マルチワードのかけ算割り算までが必要になって、結局それに付随してマルチワード計算用の各種ルーチンまで作らざるを得なくなって作ってしまった物です。その途中でツールの使いにくさにキレていろいろ改造を加えていたら今回のようなバージョンアップになってしまいましたが、できてしまった物はしかたありません。隠していても仕方ないのでこうして公開することにしました。

6.1.1 サブルーチンの概要

Page Top

このサブルーチンは、シングルワードのかけ算、割り算、マルチワード各種演算、文字列処理、モニタの操作など。必要最低限のものです。汎用サブルーチンは以下の3つのファイルに分割して収められています。

ファイル名ユニット名内容
GeneralSub.pasmGENERAL条件判断マクロ、サブルーチン呼び出しマクロなどの定義
CalcSub.pasmCALC乗除算、マルチワード演算用の各種サブルーチン・マクロ定義
StrSub.pasmSTRINGS文字列処理やモニタへの描画用サブルーチン・マクロ定義

これらを使いたい場合はプログラムの最初に

	USES	GENERAL, CALC, STRINGS

と記述して、プログラムの最後に

	INCLUDE	"GeneralSub.pasm"

と記述します。そうすれば以下のサブルーチンの全機能が使えるようになります。

サブルーチンには原則パラメータを渡さなければなりません。そのためここで利用できるサブルーチンは例えばかけ算の場合は

        LD      ^X_     @A
        LD      ^Y_     @B
        CALL    >ML_

というように、サブルーチンで定義されているポインタ型変数にアドレスを渡すという呼び出し方をします。しかしたかがかけ算のルーチンを呼ぶのに3行も費やすのはムダなので、さらに呼び出し用のマクロが用意してあります。それを使うとかけ算ならば以下のように書くだけで呼び出せます。

	&ML_	@A	@B

サブルーチンで計算が行われた場合、機械語命令同様にその結果は第1パラメータの変数に格納されます。またその結果に従って各種フラグが設定されるのも同様です。すなわち上記のマクロ呼び出しを使っていれば、あたかも機械語命令にかけ算が増えたような気分でプログラムを組んでいくことができるわけです。

6.1.2 マルチワード演算について

Page Top

マルチワード数とは複数のワードによって一つの数を表したもの。2ワードなら32ビット整数、4ワードなら64ビット整数を表します。

ここでマルチワード演算を行う場合、ワードの並びはビッグエンディアンとします。ビッグエンディアンとは複数のワードからなる値を扱う際に、上位の桁から順番にメモリに格納していく方式です。例えば 214A35F2h という2ワード数の場合、メモリに 214Ah, 35F2h の順で格納します。

逆に 35F2h, 214Ah と下の桁から格納する方式もあって、これをリトルエンディアンといいます。Windowsのパソコンなどは実はこちらの方式です。そしてこのどちらの軍門に下るかでコンピューター界はキリスト教とイスラム教のごとくに二分されているのです。

実はPMLとはその宗教戦争とはまさに無縁な自由な存在です。というのはPML仮想コンピュータは扱える値もメモリアドレス空間も、そしてメモリに格納できる値もみんな同じ16ビット、すなわち0〜65535がという類い希な特徴があるからです。このためマルチワード演算を行う場合にメモリに上の桁から収めるか下の桁から収めるなんてことはもう完全にプログラマーの趣味の領域です(ただし一度どちらかに決めたら、後はずっとそれを踏襲しないと死を見ますが)

ところが通常のCPUでは一般的に扱える数の範囲とアクセス可能なメモリアドレスの範囲は異なっていますし、そもそもメモリというのが1バイトしか書き込めないため、必然的に「マルチバイト」のデータ処理が発生します。そのときメモリに値をビッグエンディアンで格納しておくか、リトルエンディアンで格納しておくかはそのCPUの設計に完全に依存します。すなわちリトルエンディアン設計のCPUではリトルエンディアンの数でないと扱うことができないのです。

そしてここでなぜ作者がビッグエンディアンにしたかというと―――単にいままで使っていたのがリトルエンディアンばかりで飽きていたという理由です。

マルチワードルーチンでは数のワード幅、すなわち何ワードで一つの数を表すかということについて、2ワードとか4ワードと決め打ちになっていることが普通です。しかしこのライブラリでは任意のワード幅の整数が使えます。

CALCユニットにWRDWX_という変数が定義されていて、そこに以下のようなワード幅を表す定数を設定すればそのワード幅の計算ができるようになっています。

#WRDW1_	EQU	0	;1ワード(16ビット)の整数
#WRDW2_	EQU	1	;2ワード(32ビット)の整数
#WRDW3_	EQU	2	;3ワード(48ビット)の整数
#WRDW4_	EQU	3	;4ワード(64ビット)の整数
#WRDW5_	EQU	4	;5ワード(80ビット)の整数
#WRDW6_	EQU	5	;6ワード(96ビット)の整数
#WRDW7_	EQU	6	;7ワード(110ビット)の整数
#WRDW8_	EQU	7	;8ワード(128ビット)の整数

6.1.3 文字列について

Page Top

文字列とはメモリのある領域に文字、すなわち文字コードがずらっと入っている物ですが、このライブラリでは以下のように、最初のワードに文字列の長さが入っていて、次のメモリから実際の文字列が並んでいるものだとします。

アドレス100101102103104105106107108109110
文字10

6.2 GENERAL:条件判断マクロ

Page Top

以下はGENERALユニット内にある条件判断マクロです。

ある条件を満たしたらラベルLにジャンプする、というのはとても頻繁に現れる処理ですが、PMLに限らず機械語では書き方がとても分かりにくいので、もう少しユーザーフレンドリーにマクロ化したものです。そのためマクロの内容も付記しています。

6.2.1 変数の値のチェックする

Page Top

§ Xが0だった場合
&IFXZ_: Macro %X, %L
        JPF     %L      %X      ;%Xが0なら%Lへ
        EndMacro
§ Xが0でなかった場合
&IFXNZ_:MACRO %X, %L
        JPT     %L      %X      ;%Xが0でなければ%L_へ
        ENDMACRO

6.2.2 直前の計算結果のチェック

Page Top

§計算結果が0だった場合
&IFZ_:  MACRO %L
        JPT     %L      ZF      ;結果が0なら%Lへ
        ENDMACRO
§計算結果が0でなかった場合
&IFNZ_: MACRO %L
        JPF     %L      ZF      ;結果が0でなければ%Lへ
        ENDMACRO
§計算結果が0未満だった場合
&IFM_:  MACRO %L
        JPT     %L      SF      ;結果 < 0だったら%Lへ
        ENDMACRO
§計算結果が0以下だった場合
&IFMZ_: MACRO %L
        JPT     %L      ZF      ;結果 <= 0なら%Lへ
        JPT     %L      SF
        ENDMACRO
§計算結果が0より大きかった場合
&IFP_:  MACRO %L, ?L0
        JPT     ?L0     ZF      ;結果 > 0なら%Lへ
        JPT     ?L0     SF
        JP      %L
?L0:
        ENDMACRO
§計算結果が0以上だった場合
&IFPZ_: MACRO %L
        JPF     %L      SF      ;結果 >= 0なら%Lへ
        ENDMACRO
§計算結果が桁あふれしていた場合
&IFC_:  MACRO %L
        JPT     %L      CF      ;結果が桁あふれしていたら%Lへ
        ENDMACRO
§計算結果が桁あふれしていなかった場合
&IFNC_: MACRO %L
        JPF     %L      CF      ;結果が桁あふれしていなければ%Lへ
        ENDMACRO
§計算結果がオーバーフローしていた場合
&IFV_:  MACRO %L
        JPT     %L      VF      ;結果がオーバーフローしていたら%Lへ
        ENDMACRO
§計算結果がオーバーフローしていなかった場合
&IFNV_: MACRO %L
        JPF     %L      VF      ;結果がオーバーフローしていなければ%Lへ
        ENDMACRO

6.2.3 二つの値の比較

Page Top

§XとYが等しかった場合
&IFEQ_: MACRO %X, %Y, %L
        CMP     %X      %Y      ;%Xと%Yが等しければ%L_へ
        JPT     %L      ZF
        ENDMACRO
§XとYが等しくなかった場合
&IFNEQ_:MACRO %X, %Y, %L
        CMP     %X      %Y      ;%Xと%Yが等しくなければ%Lへ
        JPF     %L      ZF
        ENDMACRO
§符合なしで比較してX<Yだった場合
&IFLT_: MACRO %X, %Y, %L
        CMP     %X      %Y      ;%X < %Y (符号なし)なら%Lへ
        JPT     %L      CF
        ENDMACRO
§符合なしで比較してX≦Yだった場合
&IFLE_: MACRO %X, %Y, %L
        CMP     %X      %Y      ;%X <= %Y (符号なし)なら%L_へ
        JPT     %L      ZF
        JPT     %L      CF
        ENDMACRO
§符合なしで比較してX>Yだった場合
&IFMT_: MACRO %X, %Y, %L, ?L0
        CMP     %X      %Y      ;%X > %Y (符号なし)なら%Lへ
        JPT     ?L0     ZF
        JPT     ?L0     CF
        JP      %L
?L0:
        ENDMACRO
§符合なしで比較してX≧Yだった場合
&IFME_: MACRO %X, %Y, %L
        CMP     %X      %Y      ;%X >= %Y (符号なし)なら%Lへ
        JPF     %L      CF
        ENDMACRO
§符合有りで比較してX<Yだった場合
&IFSLT_:MACRO %X, %Y, %L
        CMP     %X      %Y      ;%X < %Y (符号あり)なら%L_へ
        JPT     %L      SF
        ENDMACRO
§符合有りで比較してX≦Yだった場合
&IFSLE_:MACRO %X, %Y, %L
        CMP     %X      %Y
        JPT     %L      ZF      ;%X <= %Y (符号あり)なら%Lへ
        JPT     %L      SF
        ENDMACRO
§符合有りで比較してX>Yだった場合
&IFSMT_:MACRO %X, %Y, %L, ?L0
        CMP     %X      %Y      ;%X > %Y (符号あり)なら%Lへ
        JPT     ?L0     ZF
        JPT     ?L0     SF
        JP      %L
?L0:
        ENDMACRO
§符合有りで比較してX≧Yだった場合
&IFSME_:MACRO %X, %Y, %L
        CMP     %X      %Y      ;%X >= %Y(符号あり)なら%Lへ
        JPF     %L      SF
        ENDMACRO

6.3 GENERAL:ウェイト

Page Top

§マウスクリックを待つ
	CALL	>MWAIT_
§指定時間のウェイトを入れる

WS_にミリ秒単位で待ち時間をセットしてサブルーチンを呼び出す

	LD	WS_	waittime
	CALL	>TWAIT_
§モニタ描画の次のフレームまで待つ
	CALL	>SWAIT_

6.4 CALC:整数演算

Page Top

以下はCALCユニット内のサブルーチン・マクロです。

6.4.1 1ワード乗除算

Page Top

以下は1ワードの乗除算のサブルーチンです。

マクロ呼び出し機能
&ML_ @X,@Y1ワードの符合なし乗算
&MLS_ @X,@Y1ワードの符合付き乗算
&DV_ @X,@Y1ワードの符合なし除算
&DVS_ @X,@Y1ワードの符合付き除算

6.4.2 マルチワード演算

Page Top

以下はマルチワード乗除算のサブルーチンです。

§データ転送
マクロ呼び出し機能
&NULX_ @XXを0で初期化する
&SETXN_ @X,@YXに1ワードの値を代入する
&LDXY_ @X,@YXにYを代入する
&CSTXY_ @X, WX, @Y, WYワード幅WXのXにワード幅WYのYを代入する(WX≠WY)
&CSSXY_ @X, WX, @Y, WY符合付きでワード幅WXのXにワード幅WYのYを代入する(WX≠WY)
&PUSHX_ @XXをスタックにPUSHする
&POPX_ @XスタックからXにPOPする
§値の比較
マクロ呼び出し機能
&ISXZ_ @XXが0かどうか比較する
&ISXN_ @X,@YXと1ワード数を比較する
&CMPXY_ @X,@Yマルチワード数同士を比較する
§論理演算
マクロ呼び出し機能
&NOTX_ @XXの論理否定を計算する
&ANDXY_ @X,@YXとYの論理積を計算する
&ORXY_ @X,@YXとYの論理和を計算する
&XORXY_ @X,@YXとYの排他的論理和を計算する
&BITXY_ @X,@YXとYのビット比較を行う
§加減算
マクロ呼び出し機能
&ADDXY_ @X,@Yマルチワード加算を行う
&SUBXY_ @X,@Yマルチワード減算を行う
&INCX_ @Xマルチワード数に1を加算する
&DECX_ @Xマルチワード数から1を減算する
&INCNX_ @X,@Yマルチワード数に1ワード数を加算する
&DECNX_ @X,@Yマルチワード数から1ワード数を減算する
§符号反転・シフト
マクロ呼び出し機能
&NEGX_ @Xマルチワード数の符合を反転する
&SRX_ @Xマルチワード数の右シフトを行う
&SLX_ @Xマルチワード数の左シフトを行う
§乗除算
マクロ呼び出し機能
&MLXY_ @X,@Yマルチワード数の符合なし乗算を行う
&MLSXY_ @X,@Yマルチワード数の符合付き乗算を行う
&DVXY_ @X,@Yマルチワード数の符合なし除算を行う
&DVSXY_ @X,@Yマルチワード数の符合付き除算を行う

6.4.3 その他のルーチン

Page Top

§疑似乱数発生

最初に1回、RNDX_にシード(0〜9999の数)を入れて呼び出すと、RNDX_に次々に乱数(0〜9999)が戻る。

	CALL	>RAND_ 

6.5 STRINGS:文字列処理

Page Top

以下はSTRINGSユニット内のサブルーチン・マクロです。

Sは文字列を保持しているメモリのアドレス、LやCは1ワード数です。

6.5.1 文字列処理

Page Top

§文字列処理ルーチン
マクロ呼び出し機能
&SCLR_ @S, L, C文字列Sの長さをLに設定して文字Cで埋め尽くす
&SLEN_ @S, L文字列Sの長さをLに変更する。短くなった場合余った分は切り捨てて、長くなった場合は半角スペースで埋める。
&SLD_ @S1, @S2文字列S2をS1にコピーする
&SADD_ @S1, @S2二つの文字列を結合する
&SCMP_ @S1, @S2二つの文字列を比較する
&STR_ @S, X符合なし1ワードの数値Xを文字列Sに変換する
&MSTR_ @S, X符合なしマルチワードの数値Xを文字列Sに変換する
§文字列コンバート
&SCONV_ @S

文字列データを作る際にいちいち文字数をカウントして設定するのは面倒なので、以下のようなデータを作っておいて、そのアドレス@Sをこのサブルーチンに渡すと、文字数をカウントして長さをセットしてくれる。

S:	DW	0,'今日は朝から夜だった生まれたばかりの……',0

6.5.2 モニタ操作

Page Top

§文字列描画ルーチン
マクロ呼び出し機能
&PRTCHR_ C1文字Cをモニタに表示する
&PRTSTR_ @S文字列をモニタに表示する
§モニタの文字色を設定するマクロ
&SETFRC_:MACRO %R, %G, %B
        OUT     #23h    %R      ;モニタ文字色の設定
        OUT     #24h    %G
        OUT     #25h    %B
        ENDMACRO
§モニタの背景色を設定するマクロ
&SETBKC_:MACRO %R, %G, %B
        OUT     #26h    %R      ;モニタ背景色の設定
        OUT     #27h    %G
        OUT     #28h    %B
        ENDMACRO
§文字表示位置を設定するマクロ
&LOCATE_:MACRO %L, %C
        OUT     #21h    %L      ;文字表示位置指定
        OUT     #22h    %C
        ENDMACRO