超多機能アセンブラ OHM-Z80

大貫信昭
 
 OHM-Z80は2パスで直接マシン語を生成するアブソリュートアセンブラです。エディタは付属していませんのでプログラムテキストの作成には別途エディタが必要です。ZEDAに比べて主に以下のような機能が拡張されていますが,すべての機能を理解する必要はありません。必要な機能だけ使ってください。拡張された機能を使わなければ,ごく普通のアセンブラとして使用することができます。
●拡張ニーモニック
 Z80のできそうでできない命令を極力なくしました。特に8ビットのLD命令では,命令表がすべて埋まります。もちろん,もともとZ80にはない命令ですから,ほかのレジスタを破壊しないてい実現するのは困難です。OHM-Z80ではAレジスタを「いけにえ」に捧げていますのでAレジスタに値を保存する場合は注意してください。
●構造化制御文
 IF文やWHILE文などの制御構造を実現します。条件式がかなり強力ですので,アルゴリズムに即した記述が可能です。ただし拡張ニーモニックも含めて,生成されるオブジェクトが不明な命令は使わないようにしましょう。
●マクロ定義
 書式はMACRO80などに比べて簡略化されてはいますが,マクロ定義やマクロ呼ぴ出しのネスティング,マクロ名の再定義が可能ですので,条件付きアセンブルと組み合わせれば結構使えるはずです。マクロ定義は期待されるほどには出番がないものですが,特殊なデータ構造の定義などに使えるかもしれません。残念ながら,ブロック疑似命令のIRPCやIRPはありません。
●条件付きアセンブル
 条件として文字列の比較もできますので,マクロ定義内て威力を発揮します。SLANGてはできなかったネスティングも可能です。
●$INCLUDE,$CHAIN
 SLANG同様ソースのINCLUDEや,CHAINが可能ですので,大きなソースを扱うことができます。また,REDA同様コマンドラインで複数のファイルを指定して順にアセンブルすることも可能です。
●REDA方式の分割アセンブル
 REDAと同じ分割アセンブルが可能です。ただし,REDAと違ってファイルごとにORGを指定する必要はありません。
●分割ファイル出力
 オブジェクトをいくつかのファイルに分割して山カすることができますので,巨大なオブシェクトも生成可能てす。REDA方式の分割アセンブルと違ってオブジェクトの管理を自動化していますので,OFFSETによるメモリ管理の必要がありません。
●モジュール化
 サブルーチンのライブラリ化を実現するために局所ラベルが可能となっています。MACRO80ではリロケータブルオブジェクトのレベルでモジュール化しますが,ソースレベルでのモジュール化を工夫してみました。考え方はほぼ同じですので,MACRO80を使ったことのある方なら簡単に理解できると思います。
 

◆ZEDAと異なる点

 S-OSユーザーに古くから利用されているアセンブラといえばZEDAだと思いますが,そのZEDAとの違いを簡単に挙げましょう。
  • ラベルの先頭文字に%,シングルクォーテーションが使用できない(ただし%は%スイッチをONにすれば使用可)。
  • ラベルに<,>,=を含むことができない。
  • ラベル定義に未定義のラベルを合むことができない(ただしスイッチで変更可)。
  • 乗除算は加減算よりも優先順位が高い(ただしスイッチで変更可)。
  • DEFB,DB,DEFW,DWのデータの区切りにコロン「:」を使用することができない(ただしスイッチで変更可)。
  • DEFM,DMのクォーテションの扱いが異なる。
 

◆注意事項

 特殊ワークエリアが4000H以上ない機種では,初期値のままではOHM-Z80を使用することができません。Xコマンドで表のサイズを変更してください。
 例)MZ-80K/Cの場合特殊ワークエリアのサイズは1000Hなので,
 ハッシュTBL:0300H
 ストラクトTBL:0300H
 マクロTBL:0000H マクロ定義は
 マクロワーク:0000H しない
 とすると,シンボルTBLのサイズは0A00Hになるはずです。
 そのほか,分割ファイル出力時,1行で1Kバイト以上のオブジェクトを生成した場合には,オーバーしたオブジェクトが正しくリスト表示されませんのでご注意ください。
 
図 メモリマップ
●テープまたはメモリ上のテキストをアセンブルし,オブジェクトをメモリ上に出力
 テープ上のテキストは一括してメモリに読み込まれてからアセンブルされる。SスイッチをONにしておくと.REDA方式分割アセンブルが可能で(テープまたはQD使用時のみ),ファイルを分けてOFFSET命令をうまく使えば,ソースを破壊しながらアセンブルすることにより,メモリ量の制約なしに大きなプログラムを作成することが可能。テキストの格納アドレスはXTコマンドで変更可。
0000H

3000H


6800H



#MEMAX
S-OS "SWORD"

OHM-Z80
 

テキスト&オブジェクト
 
●テープ上のテキストをアセンブルし,オブジェクトを分割ファイル出力
 テキストは7C00H以降に一括して読み込まれ,オブジェクトは分割出力BUFFに書き込まれて,4Kバイトずつのファイルに分割出力される。リストBUFFはアセンブルリストのためのバッファ。
6800H

7800H


7C00H



#MEMAX
分割出力BUFF

リストBUFF
 

テキスト
 
●ディスク上のテキストをアセンブルし,オブジェクトをメモリ上に出力
 テキストはクラスタBUFFに4Kパイトずつ読み込まれてアセンブルされる。オブジェクトは7800H以降に生成すること。SスイッチをONにしておくと,REDA方式分割アセンブルが可能。
6800H

7800H


#MEMAX
クラスタBUFF

オブジェクト
 
●ディスク上のテキストをアセンブルし,オブジェクトを分割ファイル出力
 テキストはクラスタBUFFに4Kバイトずつ読み込まれ,オブジェクトは分割出力BUFFに書き込まれて分割ファイル出力される。リストBUFFはアセンブルリストのためのバッファ。
6800H

7800H

7C00H


?FFFH

#MEMAX
 
クラスタBUFF
リストBUFF

分割出力BUFF
 
 
●特殊ワークエリア
0000H










#WKSIZ
ストラクト表
マクロ表
マクロワーク
ハッシュ表

シンボル表
 
ストラクト表
SIZE
マクロ表
SIZE
マクロワーク
SIZE
ハッシュ表
SIZE



 
 
〈参考文献〉
西畑文広,牛嶋昌和,「エディタアセンブラZEDA」,Oh!MZ 1985.7
瀧山孝,「改造版ZEDA」,Oh!MZ 1986.9
瀧山孝,進藤哲哉,「高速エディタアセンブラREDA」,Oh!X 1989.2
山本豊,「ザイログ形式の高速アセンブラPASS88」,Oh!PC 1985.10
大島篤,「Z-80隠しコマンド」,Oh!PC 1985.10
半田勉,「マクロプリプロセッサMCAP88」,Oh!PC 1986.4
竹原充,「アセンブラ構造化プリプロセッサSPAL」,PCマガジン 1988.2
「DDJ Cツール・ブック」,工学社
押野宗芳,「CP/MによるZ80マクロ・アセンブラ入門」,日刊工業社
林晴比古,「BASICによるブログラミング・スタイルブック」,日本ソフトパンク
 

OHM-Z80 リファレンスマニュアル

◆コマンドモード

 コールドスタートは3000Hで,ホットスタートは3003H。ホットスタート時には,シンボル表の内容が保存される。[]は省略可を表す。
●A[/[/]]
 メモリ上のテキストをアセンブルし,オブジェクトをメモリ上に出力する。A/とすると1行7バイトのリスト付きでアセンブル。A//は1行3バイトのリスト付きアセンブル(ただし,TスイッチがONの場合は1行4バイト)。
●A[/[/]]ファイル名[:ファイルネーム名[…]]
 テープまたはディスク上のテキストを読み込んでアセンブルし,オブジェクトをメモリ上に出力する。/や//を付けるとリスト付きでアセンブルする。複数のファイルが指定されたときは,それらを順にアセンブルするが,$CHAIN命令を優先する。REDAと同じ方式の分割アセンブルが可能で,そのときオブジェクトは,Vコマンドで指定したデパイスにソースファイル名の拡張子を「.OBJ」にした名前でセーブされる。1個のソースファイルに対して複数のオブジェクトファイルができる場合は,拡張子が順に「.OB2」,「.OB3」……となる。S,?スイッチ参照のこと。
●F[/[/]]ファイル名[:ファイルネーム名[…]]
 テープまたはディスク上のテキストを読み込んでアセンブルし,オブジェクトを分割ファイル出力する。/や//を付けるとリスト付きでアセンブルする。複数のファイルが指定されたときは,それらを順にアセンブルするが,$CHAIN命令が優先する。オブジエクトは分割ファイル出力バッファに書き込まれ,バッファが一杯になると自動的にセーブされる。オブジェクトはVコマンドで指定したデバイスに,最初のソースファイル名の拡張子を「.OBJ」にした名前でセーブされる。拡張子は順に「.OB2」,「.OB3」……となる。?スイッチ参照のこと。
●Sファイル名:nn1:nn2[:nn3[:nn4]]
 オブジェクトをセーブする。nn1,nn2,nn3,nn4はそれぞれ先顕,最終,実行,実際の格納アドレス。
例)STEST.OBJ:A000・AFFF
●O
 アセンブル後,すべてのラベルとその値を出力する。
●On
 アセンブル後,n回使用されたラベルとその値を出力する。
●?式
 式の値を計算し16進数で表示する。アセンブル実行後はラベルも使用可。
●#
 プリンタON/OFFを切り替える(デフォルトはOFF)。
●D デバイス名:
 ディレクトリを表示する。
●DV デバイス名
 デフォルトデバイスを変更する。
●V デバイス名
 分割ファイル出力時や,REDA方式分割アセンブル時にオブジェクトをセーブするデバイスを変更する。
●Jnn
 nnHをコール。
●M
 各機種のモニタへ。
●!
 S-OSのホットスタートへ。
●X
 現在のテキスト格納アドレスと表のサイズを表示する。シンボル表のサイズはほかの4つの表のサイズの合計を特殊ワークエリアのサイズから引いた残りとなる。値を変更したあとでOHM-Z80をセーブし直すと,次回からはその状態で立ち上がる。
●XTnn
 テキスト格納アドレスを変更する。初期値は6800H。
●XHnn
 ハッシュ表(ハッシュTBL)のサイズを変更する。初期値は1000H。
●XSnn
 構造化制御文で使用するワーク(ストラクトTBL)のサイズを変更する。構造化制御文を使用しない場合は0にしてもよい。初期値は1000H。
●XMnn
 マクロ定義した内容を登録しておくワーク(マク口TBL)のサイズを変更する。マ?口定義を使用しない場合は0にしてもよい。初期値は800H。
●XWnn
 マクロ呼び出しをした1行を保存しておくワーク(マクロワーク)のサイズを変更する。この値が大きければ大きいほど,マクロ呼び出しのネスティングも深くすることができる。マクロ定義を使用しない場合は0にしてもよい。初期値は800H。
●/[スイッチ[+または-][…]]
 スイッチのON/OFFを切り替え,状況を報告する。スイッチは12種類あり,ONにするときは直後に「+」を,OFFにするときは直後に「-」を置いて指定する。「+」は省略可能。複数の指定を羅列することができ,また指定したスイッチは再び切り替え直すまで有効。スイッチを変更したあとでOHM-Z80をセーブし直すと,次回からはその状態で立ち上がる。以下の説明はスイッチがONのときの機能。
例)/C+Y-L-
〈Aスイッチ〉
リスト表示時オブジェクトのない行のアドレスも表示する。
〈Bスイッチ〉
バッチ処理に対応しているSWORDで,エラーがあるとバッチ処理を中断する。
〈Cスイッチ〉
DB,DM,DWのデータの区切りにコロン「:」も使用できる。
〈Kスイッチ〉
ニーモニックやレジスタは小文字でもよい。
〈Lスイッチ〉
ラベル定義値の未定義ラベルのチエックをする。
〈Mスイッチ〉
マルチステートメントを許可する。
〈Sスイッチ〉
REDA方式分割アセンブル時にオブジェクトをセーブする。
〈Tスイッチ〉
リスト表示でTABコードを展開する。ただし,スイッチのON/OFFにかかわらずアセンブルは可能。
〈Yスイッチ〉
乗除算および剰余算は加減算よりも優先順位が高い(OFFの場合は加減乗除算および剰余算の優先順位はすべて同じ)。
〈1スイッチ〉
パス1でもリストを表示する。ただしオブジェクトは不定。
〈?スイッチ〉
分割ファイル出力時や,REDA方式分割アセンブル時にオブジェクトをセーブする際,キー入力待ちになる(ディスク使用時のみ。テープやQD使用時はスイッチのON/OFFにかかわらず必ずキー入力待ちになる)。
〈%スイッチ〉
シンボルの先頭に%を許す(2進数に%は使えない)。
 

◆アセンブルモード

 OHM-Z80には以下の3つのアセンブルモードがあるが,メモリ上のソーステキストをアセンブルする場合以外はいずれのモードでも複数のソーステキストファイルをアセンブルすることができる。
 また,いずれのモードでもディスク使用時は,ソーステキストファイルを4Kバイトずつクラスタバッファに読み込んでアセンブルするので,ソーステキストファイルの大きさを気にする必要がない(メモリマップ参照のこと)。
●通常のアセンブルモード
 SスイッチをOFFにして(要するになにもしないで),Aコマンドでアセンブルすることにより通常のアセンブルが行える。
 このモードではオブジェクトをメモリ上に出力し,オブジェクトのセーブは行われない。ディスク使用時はテキスト格納エリアとオブジェクト格納エリアが分離されているが,テープやQD,オンメモリの場合は分離されていないので,プログラマ自身がメモリ管理しなければならない。
 テープやQD,オンメモリの場合は6800H以降のフリーエリアにソーステキストとオブジェフトが同居しなければならないので,あまり大きなオブジェクトは生成できない。またソースを破壊しながらのアセンブルは行えない。
 ディスク使用時は7800H以降のフリーエリア一杯のオブジェクトが生成できる。
 ソーステキストファイルを複数に分けるときは,単純に分割するだけでよい。
●REDA方式分割アセンブルモード
 SスイッチをONにして,Aコマンドでアセンブルすることにより,REDA方式分割アセンブルが行える。ただし,メモリ上のソーステキストをアセンブルする場合は無効。
 このモードではオブジェクトをメモリ上に出力するが,ファイルごとに(もしくは新たにORGやOFFSETが指定されるたびに),自動的にオブジェクトを分割しセーブするので,OFFSETを指定してソースを破壊しながら複数のファイルの連続アセンブルができる。ただし,ディスク使用時はテキスト格納エリアとオブジェクト格納エリアが分離されているので,オブジェクトは必ず7800H以降に生成すること。
 複数のソーステキストファイルはコマンドラインからでも,$CHAINでも指定できるが,$INCLUDEで読み込まれたファイルは別ファイルとはみなされない。いずれの場合もファイルを復数に分けるときは,単純に分割するだけでよく,ファイルごとにORGを指定する必要はないが,ソースを破壊しながら復数のファイルの連続アセンブルを行う場合は,OFFSETをファイルごとに指定する必要がある。
 オブジェクトをセーブするときはキー入力待ちになるので(ディスク使用時は?スイッチがONの場合のみ),Yかリターンキーを押すとセーブされ,Nキーを押すとセーブされない。
●分割ファイル出力アセンブルモード
 Fコマンドでアセンフルすることにより,分割ファイル出力アセンブルが行える。
 このモードではオブジェクトをいったん分割出力バッファに瞥き込み,分割出力バッファが一杯になるか,新たにORGが指定されるたびに,自動的にオブジェクトを分割しセーブするので,ソーステキストファイルをテキスト格納バッファに収まる大きさに分割しさえすれば(テープやQDのみ。ディスク使用時はその必要もない),メモリ管理の必要が一切ない。
 コマンドラインや$CHAIN,$INCLUDEで複数ファイルをアセンプルすることが可能。いずれの場合もソーステキストファイルを複数に分けるときは,単純に分割するだけでよく,ファイルごとにORGやOFFSETを指定する必要はない。
 オブジェクトをセブするときはキー入力待ちになるので(ディスク使用時は?スイッチがONの場合のみ),Yかリターンキーを押すとセーブされ,Nキーを押すとセーブされない。
 

◆文法

■テキストの書き方

 テキストは,シンボルとステートメントとコメントで構成されている。シンボルは,必ず行の先頭から書き始め,ステートメントは先頭から1文字以上空けて書き始めなければならない。マルチステートメントが可能なので,テキストのl行には,ひとつのシンボルと複数のステートメントが記述できる。シンボルとステートメント,ステートメントとステートメントの間は,1文字以上のスベースか,コロン「:」で区切る。セミコロン「;」以降は,その行の終わりまでコメント(注釈文)として扱う。
 

■数値

 数値には,10進数,16進数,2進数,文字のASCIIコード,ラベルの値,$,$NO,およびそれらの計算値が使用できる。取り扱う数値は2バイトに収まる値で,ステートメントにより1パイトに制限される場合は下位バイトが有効となる。()が使用できるが,数値の先頭が(であってはいけない。
●10進数
 0〜9の数字による数値。
●16進数
 $で始まる16進数,またはHで終わる16進数。Hで終わる場合,先頭文字がA〜Fのときはラベルと区別するために先頭に0が必要。
例) $ABCD,1234H,0ABCDH
●2進数
 Bで終わる2進数。%スイッチがOFFのときは%で始まる2進数でもよい。
例) 110101B,%10101100
●ASCIIコード
 ダブルクォーテーション,またはシングルクォーテションでくくられた文字のASCIIコード。
例)"A","'",'"'
●ラベルの値
 そのラベルに定義された値。
●$
 アセンブル中のステートメントが置かれるアドレスを値とする。
●$NO
 行番号を値とする。主に$PRTで使用する。
●計算値
 以上の数値の計算結果。オーバーフローは無視する。
●数値で使用できる演算子
 ()と符号の十とーのほかは,すべて二項演算子である。優先順位は以下のとおりだが,スイッチの変更により加減乗除および剰余算の優先順位を同じにすることもできる。演算子の前後に空白を置くことはできない。
高い
1: ()
2: 符号の+
3: */(MOD)
4: +-
5: =く>><>=く--くくく>>
6: (AND)(OR)(XOR)
低い
●()
 数値の先頭が(であってはいけない。
例 )(LABEL+200H)*3
は不可。
  +(LABEL+200H)*3
ならよい。
●+-
 符号。単項演算子。
●+ー*/
 加減乗除。
●(MOO)
 剰余算。
例)$1234(MOD)$100は$34になる。
●関係演算子
 真なら1,偽なら0を返す。
=
<>
>
<
>=
<=または=<
等しい
等しくない
大きい
小さい
大きいか等しい
小さいか等しい
●ピット演算子
 (AND)(OR)(XOR)
例)$1234(AND)$00FFは$34になる。
●シフト演算子
 空いたビットには0が入る。
<< 左シフト
>> 右シフト
例) $80>>2は$20になる。
 

■シンボル

 シンボルにはラベルとマクロ名がある。シンボルは以下の条件を満たす文字列でなければならない。また,ピリオド2個に数字が続くシンボルはマクロ定義のロー力ルラベルとして使用されるので,注意すること。
  • 行の先頭から普いてあること。
  • 先頭文字が,$,%,0〜9,ダブルクォーテーション,シングるクォーテーションでないこと(ただし,%スイッチがONの場合は先頭文字に%を使用できる)。
  • スペース,コロン,セミコロン,カンマ,+,-,*,/,=,<,>,(,)を含まないこと。
 

■ラベル

 ラベルは,アドレスや数値データを参照するための名札。=またはASET以外で定義されたラベルは,再定義するとエラーになる。ただし,最終的に最初に定義した値と同じにすれば再定義してもよい。
 

■ステートメント

 ステートメントには,以下の5種類がある。ステートメントは先頭から1文字以上空けて書き始めなければならないが,$コマンドだけは先頭から書き始めてもよい。
  • 疑似命令
  • ニーモニック
  • 構造化制御文
  • マクロ名
  • $コマンド
 

■疑似命令

 nは1パイトの数値,nnは2バイトの数値を表す。
●ORG nn または START nn
 アセンブルするマシン語プログラムの先頭アドレスを指定する。オブジェクトを生成する前に必ず指定しなければならない。REDA方式の分割アセンブル時や,オブジェクトの分割ファイル出力時,オブジェクトファイルはORG命令ごとにも分割される。
例) ORG $A000
●OFFSET nn
 アセンブルしたオブジェクトを,ORG命令で指定したアドレスとは別のアドレスに格納するときに使用し,格納アドレスと先頭アドレスの差を指定する。ただし$PHASEと$DEPHASEの間では使用できない。
例) OFSET $8000
  ORG $3000
上の例では,3000H〜で動作するマシン鱈プログラムを3000H+8000H=B000Hから格納することになる。
 REDA方式の分割アセンブル時,オブジェクトファイルはOFFSET命令ごとにも分割される。また,オブジェクトを分割ファイル出力する場合は,OFFSET命令は意味を持たない。
●DEFB データ または DB データ または DEFM データ または DMデータ
 データがnの場合は,1バイトの数値をそのままオブジェクトとする。数値が1パイトを越える場合は,下位1バイトが有効となる。データが,"文字列"または'文字列'の場合は,文字列のASCIIコード列をそのままオブジェクトとする。"文字列"中にダブルクォーテーションを響くときや,'文字列'中にシングルクォーテーションを書くときは,2度続けて書く。データはカンマで区切っていくつでも記述できる。ただし,スイッチの変更によりコロンも区切りとして使用可。
例) DM "メッセージ", $0D, 0
  DM “PRINT ""A"" ", 0 ;PRINT “A"
●DEFW nn または DW nn
 2バイトの数値を下位,上位の順にオブジェクトにする。nnはカンマで区切っていくつでも記述できる。ただし,スイッチの変更によリコロンも区切りとして使用可。
例) DW $1234, LABEL
●DEFS nn[,n] または DS nn[,n] []内は省略可
 nnバイト分のメモリを確保する。第2パラメータのnを指定した場合はnで,省略した場合は0で埋められる。nに未定義のラベルを含むことはできない。
例) DS 80
  DS 256, $20
●EQUnn
 ラベルの値を定義する。再定義はできない。nnがラベルを含む場合,そのラベルはすでに定義されていなければならない。ただし,スイッチによリ未定義ラベルかどうかのチエックをしないようにすることも可。その場合はPhase errorのチェックもしない。
例) LABEL EQU $1234
●ASET nn または =nn
 EQU命令と同じだが,再定義ができる。
例) LABEL = $1234
  LABEL = $5678
●END
 アセンブルを終了する。END以降のテキストは無視される。テキストの最後に置く場合は省略してもよい。
 

■ニーモニック

 ザイログ表記のニーモニックを拡張したもの。
●LD命令
 LDを省略した場合はカンマの代わりにイコールを書く。使用できる第1オペランドと第2オペランドの組み合わせは別表のとおり。第2オペランドがBC,DE,HL,IX,IYの場合にかぎり第3オペランドが書ける。その場合,まず第2オベランドに第3オペランドを代入してから,第2オペランドを第1オヘランドに代入する。また,
 LD A,0
や,
 A=0
とすると,
 0AFH (XOR A)
を生成するが,0を00Hや$00などとすれば,
 3EH,00H(LD A,00H)
を生成する。
例) (LABEL)=HL=$1234
や,
  LD (LABEL), HL, $1234
は,
  LD HL,$1234
  LD (LABEL),HL
と同じ。
●CALL命令
 CALLの直後が数値の場合CALLを省略できるが,数値の先頭が$の場合は省略できない。さらに,数値の直後がRETで同一行内にある場合,JP命令に置き換えられる。
例) LABEL
は,
  CALL LABEL
と同じ。
  IF Z LABEL RET
  IF Z CALL LABEL RET
  IF Z JP LABEL
  JP Z, LABEL
はすべて同じだが,
  CALL Z, LABEL RET
はJP命令に置き換えられない。
●AND,XOR,OR,ADD,ADC,SUB,SBC,CP,EX命令
 使用できる第1オペランドと第2オペランドの組み合わせは別表のとおり。ただし,第1オペランドがAレジスタの場合は,第1オベランドを省略してもよい。CP命令で,
 CP A, 0
または,
 CP 0
とすると,
 B7H (OR A)
を生成するが,0を00Hや$00などとすれば,
 FEH, 00H (CP 00H)
を生成する。また,
 CP r, 0
の場合,
 INC r DEC r
を生成するが,0を00Hや$00などとすれば,
 LD A, r CP 00H
を生成する。
例) AND B
と,
  AND A, B
は同じ。
●INC,DEC命令
 力ンマまたは/で区切ってオペランドを複数個記述できる。オベランドにはIXH,IXL,IYH,IYL,(BC),(DE),(nn)も使用できるが,(BC),(DE),(nn)の場合はAレジスタの値を破壊する。ただし(nn)は1バイトのデータ。
例) INC HL/HL/DE
●PUSH,POP命令
 カンマまたは/で区切ってオペランドを複数個記述できる。
●RLC,RRC,RL,SLA,SRA,SLL,SRL,BIT,RES,SET命令
 オペランドに(BC),(DE),(nn)も使用できるが,Aレジスタの値を破壊する。ただし(nn)は1バイトのデータ。
●IN,OUT命令
 オペランドにA,B,C,D,E,H,L,(HL),(BC),(DE),(IX+d),(IY+d),n,(nn),I,R,IXH,IXL,IYH,IYLが使用できるが,ザイログニーモニックにない命令はAレジスタの値を破壊する。ただし,nはOUT命令でのみ使用可。(nn)は1バイトのデータ。(C)は(BC)としてもよい。
 

■構造化制御文

 アルゴリズムに即した記述を可能とするためのマクロ命令。$コマンドの$JMPが宣言されていればループ以外は相対分岐,$JRならすべて相対分岐,$JPならすべて絶対分岐に展開される。ただし,$JRでも条件がPE,PO,M,Pの場合は絶対分岐に展開される。デフォルトは$JMP。{は[で,}は]で代用可。真は0以外,偽は0。
●IF 条件式 JR nn
 IF 条件式 JP nn
 IF 条件式 CALL nn
 IF 条件式 RET
 IF 条件式 EXIT
 条件式による比較後,条件分岐を行う。ただし,条件式にANDとORの演算子は使用できない。
例) IF B<>0 RET
●IF 条件式 THEN 文1 ELSE 文2
 文1と文2にはIF THEN文は記述できない。ELSE以降は省略できる。
例) IF Z THEN SCF ELSE RCF
  IF C THEN INC A CALL ##
●IF 条件式 THEN
  文1
 EF 条件式 THEN
  文2
 ELSE
  文3
 FI
 文1をTHENとは別の行に記述するか,最初のTHENをコロンとするとブロックIF文となる。EFはELSEIF,FIはENDIFでもよい。ネスティング可。
例) IF A=O THEN
   B=1 CALL SUB1
  ELSE
   B=2 CALL SUB2
  FI

  IF A=O:B=1
  EF A=1:B=3
  EF A=2:B=5
  ELSE :B=7
  FI
●{---}
 無限ループ。脱出するにはEXIT文などを使用する。
例) {
   CALL #GETKY IF A<>0 EXIT
   CALL SUB
  }
●WHILE 条件式 {---}
 条件式が真の間ループする。条件判定はループの最初で行う。
例) WHILE (HL)<>0 {
   A=(HL) CALL #PRINT
   INC HL
  }
●UNTIL 条件式 {---}
 条件式が偽の間ループする。条件判定はループの最初で行う。
例) UNTIL (HL)=0 {
   A=(HL) CALL #PRINT
   INC HL
  }
●{---} WHILE 条件式
 条件式が真の間ループする。条件判定はループの最後で行う。
例) {
   CALL SUB
  } WHILE Z
●{---} UNTIL 条件式
 条件式が偽の間ループする。条件判定はループの最後で行う。
例) {
   CALL SUB
  } UNTIL NZ
●DO reg,初期値 {---}
 ループの最後でregから1を引き,0でなければまたループする。つまりregの値だけループする。regには,A,B,C,D,E,H,L,(HL),(BC),(DE),(nn),(IX+d),(IY+d),IXH,IXY,IYH,IYL,BC,DE,HL,IX,IYが使用できる。初期値はLDできる値やレジスタならなんでもよく省略してもよい。ただし,(BC),(DE),(nn),BC,DE,HL,IX,IYの場合はAレジスタの値を破壊する,(nn)は1バイトのデータ。
例) DO B,(DATA) {
   CALL #PRNTS
  }

  DO HL {
   PUSH HL
   CALL SUB ;HL破壊
   POP HL
  }
●EXIT
 最も内側のループ制御文から脱出する。
例) {
   A=(HL)
   (DE)=A IF A=0 EXIT
   INC HL
   INC DE
  }

■構造化制御文の条件式

n:1バイトの数値
nn:2バイトの数値
r:A,B,C,D,E,H,L,(HL),(IX+d),(IY+d),IXH,IXL,IYH,IYL
rr:BC,DE,HL,IX,IY
?:nまたはr
??:nnまたはrr
**:=,<>,>,<,>=,<=,=<,=>
●Z ゼロフラグがセットされている。
●NZ ゼロフラグがセットされていない。
●C キャリフラグがセットされている。
●NC キャリフラグがセットされていない。
●PO P/Vフラグが0。
●PV P/Vフラグが1。
●P サインフラグが0。
●M サインフラグが1。
●r**?
 rと?を比較。rには(BC),(DE),(n),I,Rも可。?にAは使用できない。**が<=か>で?がnの場合,nは0FFHという値をとることはできない。rがA以外の場合はすべてAレジスタを破壊する。ただしr=0とr<>0の場合だけは例外約にAレジスタを破壊しないが,0を00Hや$00などと普くとやはりAレジスタを破壊する。
例) IF C=3 RET
●DEC(r)**?
 rから1を引いた結果と?を比較。?にAは使用できない。**が<=か>で?がnの場合,nは0FFHという値をとることはできない。rがA以外の場合はすべてAレジスタを破壊する。ただしDEC(r)=0とDEC(r)<>0の場合だけは例外的にAレジスタを破壊しないが,0を00Hや$00などと轡くとやはりAレジスタを破壊する。
例) IF DEC(E)<>0 JR LOOP
●INC(r)**?
 rに1を加えた結果と?を比較。?にAは使用できない。**が<=か>で?がnの場合,nは0FFHという値をとることはできない。rがA以外の場合はすべてAレジスタを破壊する。ただしINC(r)=0とINC(r)<>0の場合だけは例外的にAレジスタを破壊しないが,0を00Hや$00などと書くとやはりAレジスタを破壊する。
例) IF INC(H)<D JR LABEL
●rr**??
 rrと??を比較。**が<=か>で?がnnの場合,nnは0FFFFHという値をとることはできない。Aレジスタを破壊する。
例) IF DE<=BC CALL SUB
●DEC(rr)**??
 rrから1を引いた結果と??を比較。**が<=か>で??がnnの場合,nnは0FFFFHという値をとることはできない。Aレジスタを破壊する。
例) IF DEC(IX)=0 RET
●INC(rr)**??
 rrに1を加えた結果と??を比較。**が<=か>で??がnnの場合,nnは0FFFFHという値をとることはできない。Aレジスタを破壊する。
例) IF INC(DE)>4 EXIT
●BIT(n,r)=0
 BIT(n,r)=1
 BIT(n,r)<>0
 BIT(n,r)<>1
 rの第nビットが0か1かを調べる。ただしIXH,IXL,IYH,IYLを使用することはできない。また,rにrに(BC),(DE),(nn)を使用することもできるが,Aレジスタを破壊する。
例) IF BIT(7,D)=1 THEN A=D NEG D=A
●条件式AND条件式
 条件式がどちらとも成立した場合,真となる。ORよリ優先順位が高い。
例) IF A>=“a" AND Aく=“z" THEN SUB $20
●条件式OR条件式
 どちらかの条件式が成立した場合,真となる。ANDより優先順位が低い。
例) IF A=3 OR A=5 THEN INC DE
 

■マクロ定義

●マクロ名 MACRO
 MACROからENDMまでをマクロ名の内容として定義する。マクロ名に,ニーモニックやラベル名と同じ名を付けることはできない。マクロ名が呼び出されたとき,定義した内容が展開され,定義に仮引数が使用してあれば,実引数に置き換えられる。マクロ定義のネスティング,マクロ名の再定義も可能。ただし必ずマクロ呼び出しより前に定義しなければならない。MACROとENDMはどちらもマルチステートメントにできないし,ENDMの前にシンボルがあってもいけない。また,ENDMは行の最初から書いてもよい。
例) LDIR. MACRO;LDIR. $A000,$D000,32
  HL=%1
  DE=%2
  BC=%3
  LDIR
  ENDM
●仮引数
 1番目の仮引数は%1,2番目は%2,10番目は%0となり,最高10個までの仮引数が使用できる。マクロ定義内で仮引数以外に%の文字が必要な場合は%%と記述する。置き換えは,文法を無視して機械的に行われる。
●ローカルラベル
 マクロ定義内でのみ有効なラベルを10個まで使用できる。それぞれ?1,?2,…… ?0と記述する。マクロ展開によるラベルの二重定義を防ぐためのもので,..1や..34などピリオド2個に数字が続くラベルに展開される。マクロ定義内でローカルラベル以外に?の文字が必要な場合は??と記述する。
例) RCALL MACRO ;RCALL addr
  CALL GETPC
?1:DE=%I-?1;DE=%I-$
  ADD HL,DE
  CALL [HL]
  ENDM
●REPT nn
 REPTからENDMまでの内容をnn回繰り返し生成する。nnは2バイトの数値。ネスティング可。REPTはマルチステートメントにできない。
例) REPT 4
   ADD HL,HL
  ENDM
は,
  ADD HL,HL
  ADD HL,HL
  ADD HL,HL
  ADD HL,HL
と同じ。
●EXITM
 最も内側のマクロ定義を脱出する。
マクロ呼び出し
●マクロ名 実引数
 ステートメントとしてマクロ名が現れると,マクロ定義された内容が展開される。マクロ定義中の仮引数は,実引数に置き換えられる。マクロ呼び出しのネスティング可。ただし,必ず呼び出す前に定義されていなければならない。実引数の数が仮引数の数よリも少ない場合にはヌルストリングが仮引数に波されるが,逆に実引数の数が仮引数の数より多い場合はエラーになる。
●実引数
 実引数が複数個ある場合はカンマで区切る。<と>でくくられた文字列は,<と>を含まない1個の実引数とみなされ,文字列中に>を記述するには>>と2度書く。ダフルクォーテーション,またはシングルクォーテションでくくられた文字列はクォーテーション自身を含む1個の実引数とみなされ,文字列中にクォーテーション自身を記述するには""や''と2度書く。
 

■条件つきアセンブル

 $コマンドの一種。いずれの命令もマルチステートメントにできない。ネステイング可。
●条件付きアセンブルの条件式
 条件式には,数値のほかに,数値に論理演算子のNOT,AND,ORを使用したものが使える。ただし,NOT,AND,ORの前後は空白で区切ること。優先順位は以下のとおり。真は0以外,偽は0。
高い
 AND
 NOT(単項演算子)
 OR
低い
●$IF条件式
 $ELSE
 $ENDIFまたは$FI
 条件式が真ならば,$IFから$ELSEまでを,偽ならば$ELSEから$ENDIFまでをアセンブルする。$ELSEが省略された場合は,条件式が真のとき$IFから$ENDIFまでをアセンブルする。$ENDIFは$FIでもよい。
例) $IF $>$0000 OR $く$8000
   $BELL
   $PRT HEX($),“アドレスが異常です。"
   $STOP
  $ENDIF
●$IF <文字列>,<文字列>
 文字列が等しければアセンブルする。文字列中に>を記述することはできない。比較する文字列が復数個ある場合は,カンマで区切って並べて記述する。主にマクロ定義の中で使用する。
例) @JP MACRO
   $IF <%1>,<HL,IX,IY>
    JP (%1)
    EXITM
   $ENDIF

   $IF <%1>,<BC,DE>
    PUSH %1
    RET
    EXITM
   $ENDIF

   $IF<%1>,<>
    $BELL
    $PRT $NO,“
   $ELSE
    JP %1
   $ENDIF
  ENDM
●$IF1
 パス1ならアセンブルする。
●$IF2
 パス2ならアセンブルする。
 

■$コマンド

 アセンブラに対する命令。行の先頭から書き蛤めてもよい。
●$INCLUDE ファイルネーム
 別のテキストをその場所に取り込む。ファイルネーム以後は行の終わりまで無視される。ディスク上のテキストをアセンブルする場合のみ使用できる。ネステイング可。
例) $INCLUDE SWORD.H
●$CHAIN ファイルネーム
 続きのテキストを読み込む。ファイルネーム以降は行の終わりまで無視される。メモリ上のテキストをアセンブルする場合や$INCLUDE中は使用できない。テープ上のテキストをアセンブルする場合はキー入力待ちになリ,何かキーを押すと読み込みを始め,BREAKキーを押すとアセンブルを中止する。REDA方式の分割アセンブル時オブジェクトファイルは$CHAIN命令ごとにも分割される。
例) $CHAIN NEXTFILE.ASM
●$PRT パラメータ
 バラメータを画面に表示する。パラメータには以下のものがあり,複数個ある場合はカンマで区切る。
“メッセージ" メッセージを表示する。
'メッセージ' メッセージを表示する。
数値 数値を10進数で表示する。
HEX(数値) 数値を16進数4桁で表示する。
●$BELL
 ベルを鳴らす。
●$HITKEY
 キー入力待ちになる。何かキーを押すとアセンブルを再開する。BREAKキーを押すとアセンブルを終了する。
●$STOP
 アセンブルを中止する。
●$JMP
 構造化制御文を相対分岐で展開する。ただし条件がPE,PO,M,Pの場合と,ループで届かない場合は,絶対分岐で展開する。何も指定しないと$JMPが指定されたことになる。
●$JR
 構造化制御文を相対分岐で展開する。ただし条件がPE,PO,M,Pの場合は絶対分岐で展開する。
●$JP
 構造化制御文を絶対分岐で展開する。
●$SW
 スイッチを切り管える。コマンドモードの/コマンドと同じ。ただし,アセンブルが終了するとスイッチは元に戻る。
例) $SW C+Y-L-
●$LIST
 リストを出力する。何も指定しないと$LISTが指定されたことになる。
●$XLlST
 リストを出力しない。
●$LFCOND
 条件アセンブルの偽ブロックのリストを出力する。何も指定しないと$LFCONDが指定されたことになる。
●$SFCOND
 条件アセンブルの偽ブロックのリストを出力しない。
●$LALL
 マクロ展開部分のリストを出力する。何も指定しないと$LALLが指定されたことになる。
●$XALL
 マクロ展開部分のうちオブジェクトコードを生成する部分のみリストを出力する。
●$SALL
 マクロ展開部分のリストを出力しない。
●$PHASE nn
 MACRO80の.PHASE命令とほぼ同じ。ただし必ずORGが指定ずみでなければならない。
●$DEPHASE
 $PHASE命令を解除する。
例) ORG $D000
;
#MAX  EQU $1FE5
;
    LD HL,LBL1
    LD DE,$E000
    LD BC,LBL2-LBL1
    LDIR
    CALL $E000
    RET
LBL1:
    $PHASE $E000
;
    LD DE,MSGTBL
    CALL #MSX
    RET
MSGTBL:DM “TEST",$0D,0
;
    $DEPHASE
LBL2:
    END
 

■モジュール

 $コマンドの$BEGINと$ENDで囲まれた部分はモジュールとなる。モジュール内のラベルは局所的なうべルとなり,PUBLIC宣言したラベルのほかは,モジュールの外からアクセスすることができない。またモジュールの外のラベルは,EXTRN宣言しないとモジュール内からアクセスすることができない。ただしラベルの前に$$を付ければ。モジュールの外のラベルをアクセスできる。モジュールは入れ子にはできない。モジュール内でマクロ定義をしても全域的に有効となるので,注意すること。
例) $BEGIN
;
PRTHL EXTRN ;EXTRN宣言
PRTHX EXTRN ;EXTRN宣言
;
LINDUMP::   ;PUBLlC宣言
    CALL PRTHL
    CALL $$PRNTS  ;モジュールの外
    LDB,8
LOOP:    ;局所的なラベル
    LDA,(HL) INCHL
    CALL PRTHX
    CALL $$PRNTS  ;モジュールの外のラベル
    DJNZ LOOP
;
    RET
;
$END
●PUBLlC宣言
 モジュール内でラベルを定義するとき,ラベルの後ろにコロンを2個以上続けると,そのラベルはモジュールの外からアクセスすることができる。PUBLlC宣言したラベルをモジュール内で再定義する場合も,ラベルの後ろにコロンを2個以上続ける。コロンが2個以上ない場合は,再定義された値はそのモジュール内でのみ有効となる。
例) $BEGIN
  LABEL::=$1234
   $PRT HEX(LABEL)
  LABEL::=$5678
   $PRT HEX(LABEL)
  LABEL::=$9ABC
   $PRT HEX(LABEL)
;
   $END
;
   $PRTHEX(LABEL)
●EXTRN宣言
 モジュールの外のラベルを宣言し,モジュール内からアクセスできるようにする。ただし,そのラベルは,モジュールの外ですでに定義ずみか,もしくはほかのモジュールですでにPUBLlC宣言ずみでなければならない。EXTRN宣言されたラベルはモジュール内で再定義することはできない。
例) LABEL:EXTRN
 
■エラーメッセージ
●シンボルTBL overflow!
 シンボル表があふれた。ラベルが多すぎる。
●ハッシュTBL overflow!
 ハッシュ表があふれた。ラベルが多すぎる。
●マクロTBL overflow!
 マク口定義の内容を登録しておくワークがあふれた。マクロが多すぎる。
●マクロワーク overflow!
 マクロワークがあふれた。マクロ呼び出しのネスティングが深すぎる。
●Can't EXIT
 EXITできない。
●Can't $CHAIN!
 メモリ上のテキストをアセンブルする場合や$INCLUDE中は$CHAINできない。
●Can't$INCLUDE!
 メモリ上やテープ上のテキストをアセンブルする場合は$INCLUDEできない。また,ネスティングは4レベルまで。
●Dup def label
 ラベルの二重定義。
●Illegal address!
 アドレスが正しくない。システムと重なっている。
●Illegal expression
 式が間違っている。
●Illegal OR/AND
 ORやANDは使用できない。
●Illegal register
 使用できないレジスタ。
●Illegal string
 文字列が途中で切れている。
●Illegal symbol
 シンボルが間違っている。
●Line IF nesting
 ラインIFはネステインクできない。
●Missing[(]
 (がない。
●Missing[)]
 )がない。
●Missing[,]
 力ンマがない。
●Missing ENDM
 ENDMがない。
●Missing left brace
 {または[がない。
●Missing ORG!
 ORGがない。
●Missing THEN
 THENがない。
●Missing $BEGIN
 $BEGINがないのに$ENDが現れた。
●Missing $END
 $ENDがない。
●Missing $ENDIF
 $ENDIFがない。
●Missing $IF
 $IFがないのに$ELSEや$ENDIFが現れた。
●Multi S. error
 マルチステートメントになっている。
●Out of memory!
 メモリが足りない。
●Out of renge
 数値が範囲外の値。
●Phase error
 パス1とパス2でラベルの値が一致しない。
●Relative eror
 相対ジャンプが届かない。
●Struct error
 構造化制御文の構造が間違っている。
●Struct stack overflow!
 構造スタックがあふれた。構造化制御文のネスティングは16レベルまで。
●StructTBL overflow!
 構造表があふれた。構造化制御文が多すぎる。XSコマンドで対処。
●Syntax error
 文法エラー。
●Too long line!
 1行が長すぎる。l行は128文字まで。
●Too many modules!
 モジュールが多すぎる。モジュールは254個まで。
●Undef EXTRN label
 外部ラベルが定義されていない。
●Undef label
 未定義ラベル。
●$IF nesting overflow!
 $IFのネスティングが深すぎる。ネスティングは8レベルまで。
 
[LD命令]
前\後 A B C D E H L (HL) (BC) (DE) (IX
+d)
(IY
+d)
n (nn) I R IXH IXL IYH IYL
A
B A A A A A
C A A A A A
D A A A A A
E A A A A A
H A A A A A A A A A
L A A A A A A A A A
(HL) A A A A A A A A A A A A
(BC) A A A A A A A A A A A A A A A A A A A
(DE) A A A A A A A A A A A A A A A A A A A
(IX+d) A A A A A A A A A A A A
(IY+d) A A A A A A A A A A A A
(nn) A A A A A A A A A A A A A A A A A A A
I A A A A A A A A A A A A A A A A A A A
R A A A A A A A A A A A A A A A A A A A
IXH A A A A A A A A A A A A
IXL A A A A A A A A A A A A
IYH A A A A A A A A A A A A
IYL A A A A A A A A A A A A
前\後 BC DE HL SP IX IY AF nn (nn)
BC   SP SP  
DE   SP SP  
HL SP SP  
SP        
IX SP SP SP SP SP  
IY SP SP SP SP SP  
AF                  
(nn)      
 ■:Z-80の命令。
 ●:他のレジスタに影響を与えない命令。
 ○:フラグのみ変化する命令。
 A:Aレジスタのみ変化する命令。
 SP:スタックを使用する命令。他のレジスタには影響を与えない。
[ADD/ADC/SUB/SBC/AND/XOR/OR/CP命令]
前\後 A B C D E H L (HL) (BC) (DE) (IX
+d)
(IY
+d)
n (nn) I R IXH IXL IYH IYL
A          
B A A A A A A A     A A A       A A A A
C A A A A A A A     A A A       A A A A
D A A A A A A A     A A A       A A A A
E A A A A A A A     A A A       A A A A
H A A A A A A A     A A A       A A A A
L A A A A A A A     A A A       A A A A
(HL) A A A A A A A     A A A       A A A A
(BC)   A A A A A A A     A A A       A A A A
(DE)   A A A A A A A     A A A       A A A A
(IX+d) A A A A A A A     A A A       A A A A
(IY+d) A A A A A A A     A A A       A A A A
(nn)   A A A A A A A     A A A       A A A A
I   A A A A A A A     A A A       A A A A
R   A A A A A A A     A A A       A A A A
IXH A A A A A A A     A A A       A A A A
IXL A A A A A A A     A A A       A A A A
IYH A A A A A A A     A A A       A A A A
IYL A A A A A A A     A A A       A A A A
注) △印は,A印と同じ。ただしSUB/SBC/CP命令では使用不可。
 
[AND/XOR/OR/CP命令]
[ADC命令]
前\後 BC DE HL SP IX IY AF nn (nn)
BC A A A   A A   A  
DE A A A   A A   A  
HL A A A   A A   A  
SP                  
IX A A A   A A   A  
IY A A A   A A   A  
AF                  
(nn)                  
前\後 BC DE HL SP IX IY AF nn (nn)
BC A A   A A   A  
DE   A A   A  
HL A A   A  
SP                  
IX A A A   A A   A  
IY A A A   A A   A  
AF                  
(nn)                  
[ADD命令]
[SBC命令]
前\後 BC DE HL SP IX IY AF nn (nn)
BC A A   A A   A  
DE   A A   A  
HL A A   A  
SP                  
IX A A   A  
IY A A   A  
AF                  
(nn)                  
前\後 BC DE HL SP IX IY AF nn (nn)
BC A A A   A A   A  
DE   A A   A  
HL A A   A  
SP                  
IX A A A   A A   A  
IY A A A   A A   A  
AF                  
(nn)                  
[SUB命令]
前\後 BC DE HL SP IX IY AF nn (nn)
BC A A A   A A   A  
DE A A A   A A   A  
HL A A   A  
SP                  
IX A A A   A A   A  
IY A A A   A A   A  
AF                  
(nn)                  
[EX命令]
前\後 A B C D E H L (HL) (BC) (DE) (IX
+d)
(IY
+d)
n (nn) I R IXH IXL IYH IYL
A                                        
B   A A A A A A A     A A         A A A A
C   A A A A A A A     A A         A A A A
D   A A A A A A A     A A         A A A A
E   A A A A A A A     A A         A A A A
H   A A A A A A A     A A                
L   A A A A A A A     A A                
(HL)   A A A A A A                          
(BC)                                        
(DE)                                        
(IX+d)   A A A A A A                          
(IY+d)   A A A A A A                          
(nn)                                        
I                                        
R                                        
IXH   A A A A                       A A    
IXL   A A A A                       A A    
IYH   A A A A                           A A
IYL   A A A A                           A A
前\後 BC DE HL SP IX IY AF nn (nn) (SP)
BC SP SP SP   SP SP        
DE SP SP   SP SP        
HL SP SP   SP SP      
SP                    
IX SP SP SP   SP SP      
IY SP SP SP   SP SP      
AF                  
(nn)                    
(SP)              
 
(C)1990 Nobuaki Onuki(original)
(C)1997 Junji Okazaki(edited)
(C)2024 Oh!Ishi,Nibbles Lab.(formatted)