読者です 読者をやめる 読者になる 読者になる

こんにちはマイコン制御

May FORTH be with you.

寄り道ばっかりしながら資料を探す

シルバーウィーク後半。
取り敢えず、前回でこれまでの流れでサウンドエンジンをイジったけれど、手持ちの知識では判らなくなってきて、知識の補充をすることにしました。
本当は恐らくヒントぐらいは握っているんだと思うし、トラ技の特集号をちゃんと読めば良いんだろうと思うのですが、何回か読んでも引っかからないので、多分理解する道具や手掛かりが足りなかろう、という自分マニュアル的な判断です。
恐らくさっさととりあえず形にするとしたらLPC1114>Contrex-M0>ARM>CPUの順で知識を得ていけば動く成果は手に入れられそうだけれど、きちんと理解するには逆に調べていけば良いかな、と。
無手勝流の独学なんで効率は悪いなあ。

VerilogHDL関連

ということで図書館に行って適当に見繕って本を借りました。
まずはCPUの構造の基礎ということで

コンピュータ工学入門

コンピュータ工学入門

コンピュータ工学入門はトランジスタからDNSまで広範囲なので前半ぐらいまでを流し読み。デジタルの基礎は論理回路、順序回路、記録回路あたりまで。ココらへんはVerilogHDLで鍛えられたので普通に読めます。
他のVerilogHDL本とかも斜め読みしてますが、学校でやったデジタルの基礎はかなり濃かったです。実質2週間ぐらいで0からVerilogHDLの応用ぐらいまで駆け抜けたからなあ。ただ今のところ読んだ本だとVerilogHDLの例が授業でやった内容ぐらいまでなので、逆に授業ではかなり高度な事を教えてもらっていたのですねえ。
入門Verilog HDL記述―ハードウェア記述言語の速習&実践 (Design wave basic)

入門Verilog HDL記述―ハードウェア記述言語の速習&実践 (Design wave basic)

CPU関連はMIPSアーキテクチャを例に説明されていてざーっと流し読み。概念図的な説明とアセンブラの説明になってしまって回路からだとちょっと飛躍というか、ここからCPU作るまでの橋渡し資料をもう少し見たい。内容的にはこれが良さげ

まあでも、それだともう一度CPUの創りかた読めって話かもしれない。コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方もあるし。
あと、ネット見てたらこれも良さそうな気がしてブックマーク。tatsu-zine.com

デバッガについて知る

その後再挑戦ということで

熱血!アセンブラ入門

熱血!アセンブラ入門

これだけの大著なんで当然流し読みだけれど、前読んだ時よりはだいぶ理解しながら読み進められた気がする。前回が1%の理解なら今回は5%位。
巻末のお薦めツールを見ながら、いくつかインストールしてみつつネットで調べものしたり。バイナリエディタとか関数電卓とかデバッガとか。
デバッガって自分が思っていたより凄いことが出来るものだったという事を知りました。プログラムの逐次実行だけじゃなくて(クロスコンパイル対応ってことなんでしょうか)CPUやハードウェアのエミュレーションまで受け持っているデバッガが多いのですね。
自分の環境にはデバッガはgdbはインストールされているので、追加でcgdbをapt-getで、GXemulをソースからコンパイルしてpaco通しでインストール。昔はpacoとか知らなくて管理滅茶苦茶にしていたなあ。公式サイトみたら今はporgに移行してるみたいですがMintLinuxではpacoなんでpaco使ってます。cgdb.github.io
で、GXemulのサイトを見ていたらDreamcastエミューレータもできるとの事。へー。Dreamcastソウルキャリバーは仕事で関わったんですが、我が青春の1本です。DreamcastはCPUがSH-4でWindowsCEベースだからエミュレートもしやすいのかもしれない。Linux動かしたりした例も紹介されてます。
ゲーム関連でいえばゲームボーイアドバンスからARMだったよなあ、と思ってゲームボーイアドバンスエミュレータ関連のサイトを見ていたらこんなサイトを見つけました。
The Audio Advance - Gameboy Advance Sound Resources
あれ?ゲームボーイアドバンスってARMのPWM機能を使って音だしてたんでしょうか?PWMはDACの回路が単純になるのでコストがシビアなゲーム機には良い方法なのかも。
波形メモリ音源 - Wikipedia
自分の方式では現在ではサイン波をこれでやってます。知っててやった訳ではないですが結果的に同じ方法になってました。
そういえば初代ファミコンのサウンドもPWM使ってたりするんですよ。でも単体でチップになっている訳ではないというのは今回知りました。
NES on FPGA APU

ibnizのVM

エミュレータ関連見てると楽しいんだけれど脱線ばっかりなんで、同じVMでも本来の目的に近いところも見ないと、と思ってibnizのVM周りを見てみました。そうすると非常にシンプルなヘッダファイルでVMが書かれていて感心する。これはステキかも。
ibniz公式サイトで配布されているソースの内のvm.h

#ifndef VM_H

#define MEMSIZE 0x100000
#define MAXCODESIZE 4096
#define MAXDATASIZE 4096

GLOBAL struct
{
  /* main register set */

    char  *ip;
   int32_t*stack;
  uint32_t sp;
  uint32_t stackmask;

  uint32_t*rstack;
  uint32_t rsp;
  uint32_t rstackmask;

  /* parallel register set */

   int32_t*costack;
  uint32_t cosp;
  uint32_t costackmask;
  
  uint32_t*corstack;
  uint32_t corsp;
  uint32_t corstackmask;

  /* i/o stuff */

  char     mediacontext; /* 0=video, 1=audio, 2=stdio */
  char     videomode;    /* 0=txy, 1=t */
  char     audiomode;    /* 0=mono, 1=stereo */
  char     preferredmediacontext;
  char     visiblepage;
  char     stopped;
  uint32_t videotime;
  uint32_t audiotime;
  uint32_t userinput;

  /* vm_slow-specific */

  char specialcontextstep;
  void(*pmv_func)();
  
  /* dynamic stack balance detection */

  uint32_t prevsp[2];
  uint32_t prevstackval[2];
  int      currentwcount[2];
  int16_t  spchange[2];
  int      wcount[2];

  /* memory */

  int32_t  mem[MEMSIZE];
  int      codelgt;
  int      datalgt;
  int      dataptr;
  uint32_t parsed_data[MAXDATASIZE];

  /* compiler-related (also directly executed by vm_slow) */

  char parsed_code[MAXCODESIZE];
  uint32_t parsed_hints[MAXCODESIZE];
} vm;

#endif

#define OP_LOADIMM '0'

#define ROL(a,s)   ((((uint32_t)(a))<<(s))|(((uint32_t)(a))>>(32-(s))))
#define ROR(a,s)   ((((uint32_t)(a))>>(s))|(((uint32_t)(a))<<(32-(s))))

#define IBNIZ_MUL(a,b) ((((int64_t)((int32_t)(a)))*((int32_t)(b)))>>16)
#define IBNIZ_DIV(a,b) ((b)==0?0:((((int64_t)((int32_t)(a)))<<16)/((int32_t)b)))
#define IBNIZ_MOD(a,b) ((b)==0?0:((a)%(b)))

#define IBNIZ_SQRT(a)    ((a<0)?0:(sqrt((a)/65536.0)*65536.0))
#define IBNIZ_SIN(a)     (sin((a)*(2*M_PI/65536.0))*65536.0)
#define IBNIZ_ATAN2(a,b) (atan2((a),(b))*(65536.0/(2*M_PI)))

#define IBNIZ_ROR(a,b) ROR((a),(((b)>>16)&31))
#define IBNIZ_SHL(a,b) (((b)&(32<<16))?((a)>>(((~(b))>>16)&31)):((a)<<((((b))>>16)&31)))

#define IBNIZ_ISNEG(a)  ((a)<0?(a):0)
#define IBNIZ_ISPOS(a)  ((a)>0?(a):0)
#define IBNIZ_ISZERO(a) ((a)==0?0x10000:0)

#define SWAP(t,a,b) { t tmp=(a);(a)=(b);(b)=tmp; }

さて、連休も終わり明日からまた学校です。

おまけ
昨日作ったCGを壁紙用にしてみました。
f:id:SenjiNiban:20150923210617p:plain
f:id:SenjiNiban:20150923210733p:plain