Z-80Aアセンブラから見るC言語のポインタと構造体

 現役のプログラマではありませんが ( -m-) あの頃は若かったのぅ
 今も昔も、C言語などを学び始めたら、ポイントと構造体に引っかかるようです。

 ページ構成などは、順次変わっていきます。

私なりの、言語と職種の区別
配列
BASICインタプリタ
マシン語の動作原理
マシン語の動作原理:当たり前に思えていた、命令を一行ずつ進めることとJUMP命令、大原理のひとつ
マシン語の動作原理:サブルーチンコールの前に

私なりの、言語と職種の区別
 私なりの、言語と職種の区別ですが、何十年も現場から離れていますし、また開発環境によって異なるでしょうが。

・COBOLを使っているのが事務系、金融系などの汎用機
・それ以外      制御系、産業機器・家庭用ゲーム機器・パチンコ・パチスロ・自動販売機など様々

 という、大雑把なものです。

 COBOL=事務系でしょうし、レコード単位で情報を扱い、昔からのシステムを運用しないといけないので、代替言語もなかなかないでしょう。

 それ以外はすべて制御系か?という大雑把さですが、そういう感じです。

 そして、もっとも大事なのは、会社の業務知識です。
 プログラマというと、とかくプログラム言語とかに捕らわれがちですが、もっとも必要なのは、会社の業務知識です。
 会社が、なんのために開発しているのか、それがわからないと、プログラムを作ることは出来ません。
 プログラムとは、要求を形にしたものです。

 このあたりは、以前、よく話していました。
 「プログラマとして入っても、会社のことがわからないと仕方ない」
 「一年くらいは、営業や事務で、会社のことを学習させるべきだ」
 もっとも、それはそれで、いろいろと難しい話ですが。

 開発の現場は、どこもかしこも開発秘話だらけですが、一風変わったのは、パチンコ・パチスロの開発でした。
 ネットオークションなどでは、パチンコ・パチスロの液晶部分だけを売っていたりしますが、開発現場も、それを置いていたりします。
 ネットオークションなどでは、更に、コイン不要機とかも売られていますが、関係者が作ったのでしょうね。
 それはさておき。
 「開発に関係した、パチンコ・パチスロでは遊んではいけない」という決まりがあったのですが、とあるプログラマが、パチンコ屋で遊んでいる現場を押さえられ、三ヶ月、出勤停止になりました。
 いくら開発に関係したからといって、不正に直結する訳ではありませんが、さすがに疑われる立場なので仕方ないでしょう。

配列
 今から思えば、BASICの配列も、奇妙なものです。
 a,b,c など変数に入れたらそれでいいのに、なんで a(n1), a(n2), a(n3) のように、わざわざやっているんだと思いました。

 しかしそれも、ゲームを作っていたら、気づきました。
 キャラを3体動かす部分を作っていたら・・・ x1,y1, x2,y2, x3,y3
 同じ変数を3つ用意するどころか、同じロジックを書かないといけないのでした。( -- あれ?
 そして、x(n=1〜3) y(n=1〜3) 1〜3とループさせることにより、ひとつのロジックでキャラ3体を動かせるのだと気づきました。

 BASICにはCのような構造体はなく、座標なら x y など自分で管理します。
 そして配列という概念を発明・・・発明なのでしょう。

 C言語的には x と y を構造体にして、そのポインタを渡す、という感じですが、これだけでは訳わからないでしょう。
 概念だらけです。
 実際の動作を知らず、その上に乗っている概念を理解しようとしても、それはやっぱり無理・無茶でしょう。

 このような処理は COBOL には無かったか、それほど使わなかったと思います。
 COBOL のデータ入出力はレコード単位であり、変数が沢山あるようなものです。
 COBOL 開発環境から C などに移ると、それまで知らない概念だらけになると思います。
 
 ほかの高級言語、たとえばCOBOLからC言語に移って「さぁ、今日からCです」と言われても、わかる訳がありません。
 10人のうち9人が挫折するのは、普通だと言えるような過酷さです。


 アセンブラを使ったゲームプログラムの記録です。
 オールアセンブラで投稿しておくべきでしたが、当時はそこまで考えませんでした。

 Z-80Aという8ビットCPUを搭載した、シャープのMZ-2000、X1、X1ターボという機種で、ゲームを作っていました。

 オールアセンブラ、PCG、PSG、フロッピーコントロールなど、ほぼ100%操作していました。

 ソフトハウスでエロゲーを作っていた時期もありましたが、残念ながら発売には至りませんでした。(;-- 色々とすごかった

 フロッピー媒体における、コピープロテクトの基本技もあります。

 オールアセンブラで作り出すと、フロッピーによるIPL起動も作れるようになります。

 なお、このゲームの出来は、イマイチでした・・・。

 アセンブラ部分です。マシン語のダンプリストです。


 この2冊でOKでした。
 当時は雑誌に、色々な情報が残っていました。
 たとえば上のゲームを投稿した雑誌には、一年かけて x1 の構造を説明していました。
 あの記事がなければ、x1 でオールアセンブラのゲームを作るのは大変だったでしょう。

BASICインタプリタ
 C言語のポインタは、アセンブラのアドレスと同じです。
 高級言語しか知らず、C言語のポインタを学習するのは無理・無茶のレベルです。
 アセンブラを学んだ方が速いのですが、私が知っているのはZ-80Aだけ、それで大丈夫かなと思いましたが、Z-80Aの学習をする訳でもないので、大丈夫でしょう。

 この当時の話になると、あの頃のピコピコゲームが懐かしいっていうの、語られますねぇ。
 ( --) 昔のピコピコゲーム、良かったよ   (-- まぁ・・・そだね

■THE SHARP BASIC
 今から思えば、BASICインタプリタを8bitで作っていたのって、超弩級技術者です。
 シャープは、BASICを自社開発していたそうですし、すごい人がいたのでしょう。
 
 さきほどの本ですが、シャープの方です。
 オーム社の技術本を書いているのですから、日本屈指の方でしょう。


 あの頃、ファミコンに対抗して、家電各社がMSX(SM-SEXではない)とか、自社ブランドのPCを発売したりしたのですが。
 とある会社ブランドに搭載していたBASICはシャープが作ったそうで、実際、構文はまったく同じでした。
 ただ、MZ-2000,X1にはあったV-RAMがコストの都合上無かったので、そのあたりは削られていましたが。

■スペースインベーダー
 
        @ @ @ @ @ @ @
        @ @ @ @ @ @ @   名古屋打ちの基本
        @ @ @ @ @ @ @   左から2つめに穴を開けていく
        @ @ @ @ @ @ @
        @ × @ @ @ @ @   大ヒットしたのですから、
          !           インベーダーのキャラクタ用意してくれたらいいのに・・・
          !
          !
          凸 ドピュン!!!
 
 大ヒットした、スペースインベーダーというゲームがありました。
 子供の頃、見たこともないスペースインベーダーを、遊んだことがあると言って

     ( --) へぇ、何点いったの?    (--; えと・・・75点

 一発でばれました。
 子供だったので、スペースインベーダーも100点満点だと勝手に思っていました。

 んで、スペースインベーダーにまつわる話ですが、インベーダーの数が減るほど動きが速くなるのは、当時のマシンスペックが低かった、単なる偶然という話もありますが、それは違います。
 もし、そうなら、ゲーム全体が速くなるので、自機や弾丸など、すべて速くなります。
 しかし、実際には、そうなっていません。
 wait(ウエイト)を取り、疑似マルチタスクにして、スムーズかつ自機や弾丸などの速度は一定にしていたでしょう。
 このあたりは、ゲーム作りのノウハウです。
 実際、世間一般的に「あまり、かんばしくないゲーム『○○ゲー』」は、動きがバラバラになったりします。

 開発段階では、ノーウエイトにできるので、ビームを発射した瞬間、インベーダーに当てることができるでしょう。
 目にも見えないスーパー名古屋打ちです。
 隠しモードで残していてくれたら面白かったのですが。

 最近はもう無いでしょうが、ゲーセンに置いてあるゲーム機械でも、隠しモードがあるゲームがありました。
 1機目を一発も撃たずに死んだら、2機目はフル装備になるとか。

マシン語の動作原理
 アセンブラって、なんじゃらホイと思われそうですが(;-- Cでもわからんのに、アセンブラ?
 案外と、高級言語と似ています。
 ある意味、C言語は、変態ですね。
 ほかの高級言語とは違い、C言語は、高級言語上で、アセンブラに等しいメモリ操作を実現させようとしました。
 それがポインタであり、なので、アセンブラを知らずに C言語をやろうとしても訳がわからないのですが。

 んで、まずは、こういうものなの、と。

 Z-80AというCPUは、基本は8ビットですが、レジスタを2つ組み合わせて、16ビットを実現しています。
 Z-80Aに限らず、16bitに近い8bit、32bitに近い16bit・・・CPUの基本的なアーキテクチャです。
 2つ組み合わせたら、扱える範囲が、2の乗数で、ドカンと増えるので、そうしてしまうでしょう。
 8bitのレジスタだと255までしか扱えませんが、2つ組み合わせて16bitにするだけで65535まで増えるのですから。

 8bit    16bit

 00     0000
 .      .
 .      .
 .      .
 FF(255)   FFFF(65535)  65535まで、ドカンと増えます。
               2の8乗と、2の16乗なので・・・

 レジスタというのは、変数です。
 基本的なレジスタ AF,BC,DE,HL
 変わったレジスタ IX,IY
 特殊なるレジスタ SP
 特殊なるレジスタ PC

 ・AF,BC,DE,HLには補助レジスタという裏領域があり、通常のAF,BC,DE,HLの主レジスタとEX命令で入れ替えることができます。
 ・割り込みを管理するIレジスタ、メモリリフレッシュ用のRレジスタもありますが、パソコン起動時に設定するだけで、通常は操作することはありません。

 ひとつのレジスタは8ビットなので、0〜255まで数値が入ります。
 その単独が、A,B,C,D,E,H,L となり、変数と同じようなレジスタが7つあります。
 レジスタを組み合わせて16bitにしたら、0〜65535まで数値が入り、それは、BC,DE,HL になります。
 Fレジスタはフラグレジスタという特殊なレジスタなので、AFとして演算などをすることは出来ません。

 Fレジスタの構造や動作は、ほかのレジスタとまったく違い、ビット単位で演算結果を記憶します。
 7     6     5     4     3     2     1     0    ビット番号
 Sフラグ   Zフラグ   未使用   Hフラグ   未使用   P/Vフラグ  Nフラグ   Cフラグ
 
 もっともよく使うのが、演算結果がゼロか否かを記憶するZフラグです。
 Aレジスタに20という数値が入っていたとして、Aレジスタに20という数値が入っているか確かめるため、20減算したら、結果がゼロになるので、Zフラグが1になり、比較命令として使えます。
 
 それとCフラグも多用されました。
 9ビットへの桁上がりがあるとセットされますが、ビットシフト・ローテートでも、ビットがあふれるとCフラグがセットされます。
 横スクロールにおいて、データを引き渡すなど、ゲームにおいて多用されました。
 
 あとはメモリです。
 これで、基本的な加減算、ジャンプ命令、サブルーチンコール命令、リターン命令、そしてメモリ操作ができます。
 そのうちの、メモリ操作にあたるのが、C言語のポインタです。

マシン語の動作原理:当たり前に思えていた、命令を一行ずつ進めることとJUMP命令、大原理のひとつ
 命令が、一行ずつ上から下へ進むのは、高級言語では当たり前ですが、マシン語(アセンブラ)では、それも原理です。
 そして、ジャンプ命令、サブルーチンコール命令、リターン命令、これらが実行できることになります。
 Z-80Aという8bitのマシン語でも必要なことは揃っており、基本は変わりません。

 1:A=20H
 2:A=A+C      (゚゚ ほとんど高級言語
 3:A++         実は、アセンブラのニーモニックに、そのままあるんですよ
 4:Jump 3000H

 上から下に一行ずつ進む命令ですが、実はそこがジャンプ命令につながります。
 そもそも、どうやって、一行ずつ進むことが出来るのか、ですが、特殊レジスタPCが常に動いています。
 PCレジスタとは、プログラムカウンタという意味です。

  (..) 実際のZ-80Aアセンブラ&アセンブリです。
  (..) 3E 20 89 3C C3 00 30 がダンプリストになり、マシン語はここだけ見て「なんだこれ・・・」となります。

  アドレス マシン語  ニーモニック
1 0000   3E 20    LD A,20H     この命令は2バイトなので、PC(プログラムカウンタ)に2加算
2 0002   89     ADD A,C      この命令は1バイトなので、PC(プログラムカウンタ)に1加算
3 0003   3C     INC A       この命令は1バイトなので、PC(プログラムカウンタ)に1加算
4 0004   C3 00 30  JP 3000H     PC(プログラムカウンタ)に、3000Hを入れる
                      30 00 ではなく、00 30 になるのは、Z-80Aは、上位8bitと下位8bitを入れ替えるため

・命令のバイト数だけPCレジスタを加算することにより、上から下に一行ずつ進みます。
・JUMP命令は、PCレジスタにJUMP先のアドレスを入れます。

つまり、ジャンプ命令とは、PCレジスタへの値の代入であり、LD PC,3000H が動作原理に等しいです。
        しかし概念的にJP(ジャンプ)なので、アセンブラレベルでも JP 3000H という構文になっています。

こうして、上から下に一行ずつ進み、JUMPもできるようになります。
一歩ずつ進むことも、ジャンプも同じ、なんだか格言のようですが、それがマシン語の実際です。

・基本中の基本、命令が上から下へ進むことさえ、概念、命令を取り出すアドレスを変えることです。
・命令バイト分加算して次行に進むか、アドレスを代入してジャンプとするか、この2つの概念しか作れなかったので、3つめの概念を作れば大発明になるでしょう。

マシン語の動作原理:サブルーチンコールの前に
 ジャンプ命令は実現できたのですが、これではサブルーチンコールはできません。
 サブルーチンに飛ぶことはできますが、戻ることができません。
 マシン語で一体どうやって、サブルーチンコール及びリターンを実現しているのか、ですが、
 
 その基本原理につながる特殊なるレジスタ SP を説明します。
 SPレジスタとは、スタックポインタのレジスタです。
Counter