############################################################################## # # # S−OS講座・第1回「コマンドからアセンブラまで」 # # # ##############################################################################  私が、今回からふつつかながら講師を努めさせていただく、森と申します。皆さんお 付き合いの程、よろしくお願いします。  さて、「S−OS」といってもご存じない方もいらっしゃるかも知れませんので、今 回はS−OSについての概略から、始めたいと思います。  S−OSは、1985年5月、当時の「Oh!MZ」誌上で開始された、パソコン全 機種共通化の試みです。Z80パソコンシステムを対象として、互換性のない異機種間 で、共通のマシン語プログラミング環境を実現することを目的にしています。  従来の環境では、例えば、シャープのパソコンとNECのパソコンとの間には通常ソ フトウェアの互換性はありません。さらに、同じシャープでも、X1用のプログラムは MZでは働きませんし、その逆も不可です。また、MZというネーミングが同じでも、 1500と2500では互換性がない...といった有様です。  しかし、現実にはPC/MZ/X1は同じCPU(Z80)ですし、表示能力、キー ボード(文字種)、ディスクドライブなど、(細かい点には目をつむれば)ハード的な 基本仕様はどれも似たり寄ったりであることに気付きます。このことは、「互換性のな いのはメーカのソフトウェアに対する方針なのであって、ユーザが積極的に互換性を求 めれば、自ずと道は開ける」事を示しています。     ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  S−OSは、これら互換性がないと思われている各機種の機能を統一し、ユーザに共 通のマシン語環境を提供する(つまり対応機種で同じマシン語プログラムが動く事を意 味する)システムなのです。(決してX1専用のプログラムをMZで動かせるようにす るようなものではない)  それでは、この「互換性の確保」を、S−OSではどの様にして実現しているのでし ょうか?  各機種には、マシン語プログラムの開発に便利な様に、マシン語モニタなるものが提 供されています。モニタというと、雑誌に掲載されたダンプ・リストの入力のとき、  MON というコマンドで呼び出される事をご存じの方もいらっしゃると思いますが、実際のモ ニタプログラムは、単にダンプ入力するだけのものではなく、例えば、画面に文字を表 示(BASICのPRINT)するだとか、キーボードから1文字読む(BASICで はINKEY$ですね)だとかいう、よく使う機能を、ユーザプログラムから呼び出し て利用することができるようになっている(これをモニタ・サブルーチンという)ので す。実はこのモニタ・サブルーチンを利用する手続きが機種によって異なるため、いま まで全機種で使用出来るプログラムが書けなかったのです。  そこでS−OSでは、この各機種ばらばらのモニタ・サブルーチンの呼び出し方を共 通化しました。つまり各機種のモニタをそっくりそのまま拝借して、利用する手続きだ けを統一したわけです。これでS−OSの仕様に従ったプログラムならば、どの機種で も同じように使用できるようになりました。ここが他のCP/Mなどのシステムと違う ところで、共通化を図りながら、各機種に密着した部分を残す(つまりX1のS−OS はX1風、MZのS−OSはMZ風なんですね)という、面白いシステムになっていま す。  例として、画面に文字「A」を出す時の、各機種及びS−OSの場合の比較をやって 見ましょう。   BASIC  |   マ シ ン 語 ( ニ ー モ ニ ッ ク )          |   PC     X1     MZ    S−OS −−−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−  PRINT”A”| LD A,41H LD A,41H LD A,41H LD A,41H          | CALL 0018H CALL 0013H CALL 0840H CALL 1FF4H          |    ↑      ↑      ↑      ↑  この表を見れば分かるように、矢印の数字(16進数です)が違うだけですね?これ は、「一文字表示する」モニタ・サブルーチンのエントリ・アドレス(プログラムがメ モリのどこに入っているかを示す番地)といわれ、これが表のように各機種のモニタで 異なるため、同じマシン語プログラムが働かないのです(大概の場合、この程度の違い であることが多い)。S−OSでは、これを全機種とも同じ(一文字表示の場合は、1 FF4番地)とすることで、共通化を実現しているのです。 ***  それでは実際に,S−OSのオペレ−ションへと進んでいくことにしましょう。 まず、”SWORD”のシステムを起動すると、次のような画面となります。 ___________________ | | <<<S−OS SWORD>>> | | #■ ←カーソル | | この”#”マークは、”SWORD”のプロンプトです。BASICなら”Ok”、C P/Mなら”A>”と同じで、SWORDのコマンドが入力可能な状態を表わします。  ”SWORD”には、次の11種のコマンドが用意されていて、”#”マークが表示 されている時にこれらを使用することができます。 ____________________________________ | | | #D[<デバイス名>:] | | ……ファイル名一覧の表示。 | | <デバイス名>を省略すると、デフォルトデバイスの一覧を表示 | | する。 | | | | #DV<デバイス名> | | ……デフォルトドライブの変更。 | | | | #S<ファイル名>:<開始番地>:<終了番地>[:<実行番地>] | | ……メモリの内容をデバイスに書き出す。 | | | | #L<ファイル名>[:<ロードアドレス>] | | ……<ファイル名>で指定されるプログラムをデバイスから読み込む。| | (Binファイルのみ) | | | | #J<アドレス> | | ……<アドレス>で示すメモリの番地(16進数4桁)をサブルーチ | | ンコール 。 | | | | #K<ファイル名> | | ……ファイルをデバイスから削除。 | | | | #N<旧ファイル名>:<新ファイル名> | | ……ファイル名の変更。 | | | | #ST<ファイル名>:P(またはR) | | ……ファイルに書き込み・消去禁止属性をつける。または属性を解除 | | する。 | | | | #M……各機種のモニタを呼び出す。 | | | | #W……画面モード(40/80桁)の切り替え(一部機種不可)。 | | | | #!……ブートコマンド(リセットがかかる)。 | | |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  それでは実際に”SWORD”のコマンドを使ってみましょう。例えば、デバイスA (1台目のドライブ)のファイル一覧を見るには #DA: とします。例えば、 Bin A:ABC   .  :3000:30FF:3000 と表示されたなら、このプログラムは、3000H番地から30FFH番地の256バ イトの大きさで、3000H番地から実行されることが分かります。(番地、アドレス などのことばについては、あとから説明します)  ここで表示された一覧の先頭に”Bin”と表示されているファイルはLコマンドで 読み出すことができます。 #LA:ABC とキーインすれば、メモリ上にロードすることができます。ロードしたプログラムを実 行するには #J3000 とキーインすればよいのです。さらに、メモリ上の3000H番地から3FFFH番地 の内容をファイル名”BCD”で保存したければ #SA:BCD:3000:3FFF:3000 とキーインすればよいわけです。  また、お手持ちの”SWORD”システムがRUN&SUBMIT対応の場合は, (当会会報「S−OS通信」のシステムは対応済です) #[スペース]<ファイル名> をキーインすることにより、プログラムのロードと実行を一度に行うことができます。 また、パラメータを必要とするプログラムの場合は、 # <ファイル名>:パラメータ1:パラメータ2:…… のようにして、コマンドラインからパラメータを渡すことができます。例えばTYPE というプログラムの場合は # TYPE:<ファイル名> とキーインすることで、指定ファイルの内容を見ることができます。このようなプログ ラムのことを「トランジェントコマンド」といいます。 *** コマンドはこれぐらいにして,次にアセンブラを使ったZ80のマシン語作成へと話 を進めたいと思います。  普通マシン語のプログラムを作成するには,記号語(ニーモニック)で書かれたプロ グラムを16進数のマシン語に変換するツール(アセンブラ)が必要です(昔はハンド アセンブルといって,手作業で置き換えていた時代もあった。慣れてくると,16進数 で直接プログラミングしたりして,人間アセンブラといわれる職人芸も存在した?)。  S−OS”SWORD”で使えるアセンブラとしては,ZEDAやREDAなどがあ りますが,ここでは都合上,当方でZEDAとエディタのE−MATEを合体させたも の(Z−MATE)を用意しましたので,これで進めさせて頂きます。(Z−MATE については,本誌のZ−MATE.DOCをご覧ください) ※注.以降<CR>はリターンキーを表します。  まず最初に,S−OS”SWORD”を起動すると,プロンプト”#”が画面上に現 れます。ここでAドライブにZ−MATEの入ったフロッピーをセットして # Z−MATE <CR> を押します。これでエディタが起動しました。  それでは,簡単なプログラムを入力して見ましょう。いまカーソルはエディタのコマ ンド行に表示されています。ここでEをキーインし,<CR>キーを押します。すると カーソルが破線の下へおりて,プログラムが入力できる状態になります(エディットモ ード)。ここで次のとおり打ち込んでください。 ORG 8000H ;8000H番地より始めよ LD A,(8010H) ;8010H番地の内容をAレジスタへ LD (8011H),A ;Aレジスタの内容を8011H番地へ RET ;S−OSに戻る  各行の先頭は空白を1つ以上あけてください。また1行の最後は<CR>キーを押し ます。なお,”;”以降はコメントですので入力する必要はありません(入力しても無 視します)。全部うち終えたなら,<ESC>キー(またはBREAKキー)を押すと コマンド行にカーソルが戻ります。  つぎに,A<CR>とキーインすると,画面がクリアされて A> という表示が現れます。これは,アセンブラモードのプロンプトです。ここで A>A// とキーインすると,画面はニーモニックがマシン語に変換されたリストを表示します。  打ち込んだプログラム(ニーモニック)がどう16進数(マシン語)に変換され,メ モリに格納されたか見てみましょう。 A>D8000<CR>  とキーインしてください。メモリの8000H番地(16進数では,数字の末尾にH をつけます。数字の先頭に$をつける人もいます)から128バイトの内容が表示され ます。 :8000 3A 10 80 32 11 80 C9 …… : …… :8010 00 00 00 00 00 00 00 …… : ……  ↑ここの内容は不定 ”:”のつぎの4桁の16進数がアドレス(番地)を表し,そのつぎから始まる2桁の 16進数がそれぞれ8000H番地の内容,8001H番地の内容,……となります。 この”3A”から”C9”までが,打ち込んだプログラムがマシン語に変換された部分 です。 LD A,(8010H) → 3A 10 80 LD (8011H),A → 32 11 80 RET → C9 メモリ(主記憶)のようす 〜〜〜〜〜 8000H番地→| 3A | 8001H 〃 →| 10 | 8002H 〃 →| 80 | | …… | 番地(アドレス)とはメモリの場所 8006H 〃 →| C9 | を示す数字 〜〜〜〜〜 さらに細かくみると,LD A,(〜)が3Aとなり,かっこの中の8010Hは10 80と,真ん中で前後がひっくりかえっています。Z80では,4桁(2バイト)のデ ータはこのように,上位と下位が逆転します。注意しましょう。  また,”ORG 8000H”に相当するマシン語がありませんが,これはORGと いう命令がマシン語の命令ではなく,アセンブラに指示を与えるためのもの(ORG命 令の場合,プログラムの先頭アドレスを指示する)であるからです。このような命令を 「疑似命令」といいます。  さて,Dコマンドにより表示されたメモリの内容は,ただ見るだけではなく,書き換 えることができます。カーソルを8010H番地の位置へもっていき, :8010 55<CR>    ̄ ̄ と,キーインしてください。その後画面をクリアして(<CLR>キーを押す)もう一 度 A>D8000<CR> とキーインすれば,確かに8010H番地の内容が55に変わっています。  それでは,このマシン語になったプログラムを実行することにしましょう。プログラ ムは8000H番地から格納されましたので, A>J8000<CR> とキーインします。すると一瞬で実行は終わり,ふたたび”A>”が表示されます。メ モリの内容はどうなったでしょうか。もう一度 A>D8000<CR> とキーインしてください。 :8000 3A 10 …… : …… :8010 55 55 …… : …… と,8010H番地の内容が8011H番地にコピーされたと思います。  最後に,エディタへ戻るには, A>E <CR> を押し,エディタからS−OSのコマンド待ちに戻るために!<CR>を押します。  以上が,Z−MATEを使ったマシン語の開発スタイルです。これでだれにでも簡単 に(勿論ニーモニックを覚えなければなりませんが,必要な命令はさほど多くありませ ん),マシン語が勉強できるものとおもいます。 *** それでは次に,S−OSのサブルーチンの使い方へと移りたいと思います。  さて,皆さんがBASICでプログラミングされる時,例えば画面に1文字出す場合 PRINT ”*” のように書かれることと思います。これをソフトウェアの力を借りずにマシン語で同じ ことをやろうと思えば,マシン語の知識のほかに,ターゲットマシン(ご使用のパソコ ン)のハードウェアについて理解しなければなりません。具体的には,ちょっと難しい 話になりますが,ビテオRAMはメモリ空間かI/O空間か,アドレスは何番地から始 まっているか,バンク切り替えの方法はどうだとか...これらのことが機種ごとに異 なるから,異機種間でソフトの互換性がないということは前に書きましたが。  ところが,S−OSでは,これらのハードを直接操作すれば極めて複雑な処理を,B ASICのステートメントのように簡単に肩代わりしてくれるサブルーチンが用意され ています。  前述の「PRINT ”*”」と同様な動作をさせるには,アセンブリ言語で次のよ うに書けばいいのです。 ORG 8000H ;開始番地は8000H LD A,’*’ ;Aレジスタに星印を入れる CALL 1FF4H ;1FF4H番地〜を呼び出す RET ;終わり(モニタへ戻る)  先に,Aレジスタへは数値を代入しましたが(実は0〜255の値です),このよう に文字でも(1文字)入れることができます。「CALL命令」は,指定した番地から 書かれているプログラムを呼び出す命令です。「CALL 1FF4H」により,プロ グラム・カウンタ(PC;現在実行中の命令が書かれているメモリのアドレスを示すレ ジスタ)は1FF4Hになり,そこから順に書かれている命令を実行していき,「RE T」命令にぶちあたると,もとの場所(CALL命令の直後)に戻ります。  メモリ |_______|  −→1FF4H| |(1文字表示するプログラムが  ↑ | | はいっている)  | | |    |←−−−−戻る |RET |(1文字表示ルーチンの終わり)    | ↑ | |    | | 〜〜〜〜〜〜〜〜〜    | | 8000H| |    ↓ |←−−飛ぶ |CALL |    −−−−−−−→ |(次の命令) |  S−OSでは,1FF4H番地から(厳密にいえば少し違いますが),Aレジスタの 内容を文字として表示するプログラム(サブルーチン)が予め用意されていて,ユーザ ーはこれをCALL命令で呼び出して使うことができます。  しかし,「1FF4H番地」と「1文字表示」とを結び付けて覚えるのは大変なので これに名前をつけてやります。次のプログラムを見て下さい。 #PRINT EQU 1FF4H ;1FF4H番地に名前を付ける ; ORG 8000H LD A,’*’ CALL #PRINT RET  これで「1FF4H番地」=「1文字表示」と覚える必要はなく,「#PRINT」 =「1文字表示」と覚えればいいわけで,だいぶわかりやすくなりました。このように 番地に名前を付けたものを「ラベル」といいます。S−OSのサブルーチンは,慣習に より,ラベル名の先頭に”#”を使います。 *** 今回はここまでです.次回があれば(不定期刊行なもので),Z80のレジスタ,プ ログラムの分岐/ループなどについて解説したいと思います. まとめ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− ・ORG nn   ……プログラムの先頭アドレスをアセンブラに通知する。 ・LD A,(nn)……メモリのnn番地の内容をAレジスタに読み出す。 AレジスタはCPUが持っているデータの記憶場所で,大き さは8ビット(故Z80は8ビットCPU). ・LD (nn),A……メモリのnn番地へ,Aレジスタの内容を書き出す。 ・RET   ……呼び出し元のプログラムへ戻る。S−OSのモニタ(コマン ドモード)から呼び出されればS−OSへ,アセンブラから 呼び出されればアセンブラへ戻る。 ※nnは2バイトの定数。Z80では,アセンブル後上位と下位の順が逆になる。 ・ラベル名の定義  <ラベル名>  EQU アドレス  以降アドレスを記述するかわりに,ラベル名がつかえる。 (例)  SORC  EQU 8010H  DEST  EQU 8011H  ;  ORG 8000H  LD A,(SORC)  LD (DEST),A  RET ・CALL命令  サブルーチンを呼び出す。1文字出力の方法は以下の通り。 #PRINT  EQU  1FF4H  LD A,’文字’  CALL #PRINT PS.本コーナーにご意見ご要望をお寄せください。「S−OSネット大阪」におこし くだされば,レスポンスもいたします. (EOF)