January 2009 Archives

AVR-SD拡張回路(また改良)

| 2 Comments | No TrackBacks

前回の回路がまた間違ってました。

  1. アドレス線を使いたければ、データ線と同様ラッチしなければいけない
    これまでデータ線のみでアドレスのラッチを忘れていました。データのタイミングがAVRの割り込みからは間に合わないので、同然アドレスもラッチする必要があります。
  2. ラッチではなくてフリップフロップを使う必要がある(かも)
    出力リクエスト時の^WRとデータ線の確定タイミングは、8080ではデータが先に確定します。これに対し、8085や8086では^WRが先に確定するので、ラッチだと瞬間的にでたらめなデータがAVRに取り込まれる可能性があります。 Z80のドキュメントを調べてみたところ、CMOS版のZ84C004では"Data stable prior to /WR Fall"が-140ns~-10nsで、WRが先に確定することがあるようです。 実際にはAVRの反応はこれよりはるかに遅いことと、^IORQなど他の信号線とORをとっていることで実害はないと思いますが、念のためFlip Flop(374)を使うことにします。

先日日本に行った際に4075(3OR)は手に入らなかったので(代わりに4072(4OR)を買ったけど)、4078(8OR)を使って、占有I/Oアドレスをひとつだけで行くことにしました。 ソフトウェア的にはコマンドのための通信量が増えるのですが、まぁこれはトレードオフでしょう。 これ以上汎用ロジックICを増やすと、通常のDIPを使っている関係上、基板に乗り切らなくなってしまいますし、CPLDを使ったほうが簡単になるので。

というわけで、修正した回路が以下です。 I/Oアドレスは0x00に固定してしまいました。安直...。

20090127-AVR_SD-OR8.PNG

この修正で、ATmegaの6本ものI/Oが余ることになりました。 あと一つ減らすとATtiny861(20ピン)でも足りることになるのですが、実際にはRAM容量の関係(512Bytes)でちょっと厳しいですね。 FATでは512バイトのバッファを取らないとかなり性能的に厳しいので。

あ、XCKもXTAL1/2も空いているので、ATmega88(以上)なら外部クロックを使って高速に動作させることができますね。

デュアルリンクのUSBってアリ?

| No Comments | No TrackBacks

USB 2.0が普及して久しいですが、ハードディスクやモニタなど高速デバイスの利用にはいささか苦しい場面も出てきました。 バックアップ用途のハードディスクなどなら別にそれほど気にすることもないとは思いますが。

USB 2.0の論理的な帯域は480Mbps(60MB/s)ですが、バルク転送時の転送速度は約53MB/sとなります。 帯域保証ができるアイソクロナス転送となると約24MB/sです。 現在の高速HDDは100MB/s以上のスピードを持つものも多く、SSDに至っては200MB/sを超えるものもあります。 Gbit Eternetも、実際のスループットは置いておいても、USBの規格上限を大きく上回っています。

巷では帯域が5Gbps(625MB/s)となるUSB 3.0の規格策定が行われているようですが、一般に利用可能になるのはまだ先の話でしょう。

そこで、Dual Link DVIのように2本以上のUSBケーブルで機器と接続するのはどうでしょう? ハブを介したら意味がないですが、今やデスクトップなどでは8個くらいのUSBポートを持つ機種も増えていますし、ノートPCでも多数のUSBポートを持つ機種があります。 私の利用しているPortegeの場合、本体に3ポート、ポートリプリケータをつけると合計7ポート利用できます。 そのうち2個(以上)を利用して高速なデバイスを接続するということです。

以前から電源供給(500mW/port)の観点から2ポートのUSBを利用する機器はHDDを中心として結構ありますが、通信路として2ポート以上のUSBを同時に使う機器は見たことがありません。

2個以上のポートをどのようにうまく制御するか、コントローラやOSが対応するのかなどの課題はありますが、USB周りのチップは低価格なので、新たな規格を作ったりするよりも安価なソリューションになると思うのですが。

こういうの、ダメですか?


リタリンについて

| No Comments | No TrackBacks

私は抑うつからHypersomnia(過眠症)を併発して、以前は仕事もできずひどい有様でした。 夜はちゃんと寝ているのに、昼間どうしても寝てしまうのです。 昼間寝てしまったりボーっとしている→仕事できない→上司にしかられる→鬱がひどくなる、という悪循環に陥っていきました。 服用するanti-depressantは強くなっても、この症状は改善しませんでした。

その後、引越しに伴い病院を変わったりして調べた結果、原因のひとつは抑うつのために飲んでいた薬にもありました。 Anti-depressantは眠くなる薬なので、(それを知らずに)一日何度かに分けて飲んでいたため、余計眠くなっていたそうです。 特にスルピリド(ドグマチール)が悪いらしく、主治医に「よくそれで起きていられたねぇ」と呆れられてしまいました。

その後、いろいろ精密検査などをしたところ、眠りの質が極めて悪いことがわかりました。 そのため、主治医の厳密な管理の下、リタリンを服用するようになりました。

他の薬も飲み方を工夫(寝る前にまとめて服用する等)して、睡眠と覚醒を薬でコントロールするようにしました。 その効果は絶大で、仕事に集中できるようになり、鬱もだいぶ良くなりました。 それでも昼寝してしまいますが、時と場所をわきまえず寝ていた以前と比べると大改善です。 Anti-depressantにsleep aid、minor tranquillizerと、飲む薬は多くて大変ですが、症状が目に見えて改善したので続けています。

まぁ、逆に切れると大変なので、渡英する際は万全の準備を整えました。 私にとっては「命の薬」といえるくらい必要なものですので。 イギリスには「リタリン」はありませんが、同じ成分の薬はEquasymという名のものが入手可能です。 私の場合、英文のmedical certificateを持参し、普通にGPから処方してもらうことができました。

少し前(2007年くらい)から、日本ではリタリンの規制が強化されて、Web上ではリタリンまたは代替薬(コンサータ等)の入手のための情報交換が活発ですが、本当に必要な人とそうでない人が入り混じっているようで、情報入手には細心の注意を要しますね。

2ちゃんねるを検索してみたときは驚きました。 違法な個人販売情報が飛び交っているんですね。 1錠1000円とか1500円とか、アホかと思います。 しかもそんな価格でほしいという人までいる。 そんな金出してまで買っていったいどうしようというのでしょう?? もともと保険適用で30円とか(自治体の精神医療指定を受けるとその1/3)、その程度の薬価なのに...。

こういう活動が、本当に必要な人を窮地に追いやっているのでしょう。

2007年10月のリタリン添付文書改訂では、リタリンの適応から難治性うつ病が除外されました。 それは別にいいのですが、私のように(厳密にはナルコレプシーではないかもしれない)睡眠障害にもちゃんと適応にしてほしいものです。 ナルコレプシー以外の睡眠障害がまだまだマイナーな分野で、専門医も少ないことが原因のようですが...。


Scalaのimplicit defの不思議な挙動

| No Comments | No TrackBacks

まだ理解が浅いせいか、Scalaでimplicit defを使っていて、ちょっと不思議な挙動に出くわしました。

次のようなコードを実行します。

object test extends Application {
  var count = 0
  implicit def declare(property: String) = {
    class A {
      def plus(a: Int):A = { count = count + a; this }
    }
    new A
  }
  "a" plus 1 plus 1 plus 1
  println(count)
}
  

"a"はimplicit defにかかり、Aを返します。 その後、そのオブジェクトに対してplus 1を3回実行しています。 というか、そのつもりです。

結果は、7と表示されます。

  "a" plus 1 plus 1 plus 1
  

の部分を以下のようにすると、

  var a = "a" plus 1
  a plus 1
  a plus 1
  

期待通り3が出力されます。

デバッガで追いかけても、確かに"plus 1"の回数をnとすると、関数plusが2^n-1回実行されているようです。

う~ん、不思議。


SDHCの後継規格SDXCは不安がいっぱい

| No Comments | No TrackBacks

32GBの壁(本当は壁じゃない)が問題となっていたSDHCの後継規格、SDXCがようやく発表されました。

速度(今年中に104MB/s、ロードマップ上は300MB/sまで)はともかくとして、容量上限が2TBということなのですが、大丈夫かしらん? この程度ではあまり将来を見据えているとは思えませんねぇ。 SDHCの二の舞(あっという間に最大容量に到達)にならないか心配です。

ちなみにフォーマットについては、exFATになるようですが、以前お伝えしたようにライセンス上不透明な部分があります。 われわれのような個人がデバイスドライバを勝手に作れるのかどうか、現時点ではなんともいえません。 また、現在exFATはWindows XPではサポートされておらず、Windows Vista SP1(およびWindows Embedded CE 6.0)からのサポートとなります。

ちなみにexFATの規格からすると、これは64bit FATとでもいえるもので、2TBではなく16EB(Exabyte)までサポートしています。SDHCのときは物理的に2TBまでサポート可能なのにもかかわらず32GBまでのサポートにとどめていましたが、今回はその2TBが上限ということで、なんか釈然としません。

なんか発表の瞬間からして不安な要素いっぱいな気がするのですが...。

PSGPCM再生時のクロックの話、再び

| No Comments | No TrackBacks

性懲りもなくPSGPCMと格闘しています。

PSGによるPCM再生は、以前11kHz/9ビット相当の比較的高音質の再生を成功させましたが、マシンパワーおよびメモリを非常に消費する方法でした。

そのため、来るべき(?)画像と音声の同時再生に向け、いかに「軽く」発音させるかについても少し検討してみることにしました。 まずはテストとして、PSG 1チャネルで8kHz/4ビットの再生を試しました。

すると、またしてもクロック数計算が合わない事象に出くわしてしまいました。 以前はI/Oウェイトの考慮漏れが原因でしたが、今回はそうでもない感じです。

データはpacked 4bit(1バイトの上位4ビット、下位4ビットにそれぞれ音量データを格納する方式)で作成しました。 再生ルーチンの中心部は次のようになっています。

	; 割り込みは禁止、DMA OFF
	; あらかじめ音量や周波数は設定しておく
	; ポート0xa0に8を出力しておく(出力チャネルのラッチ)
	; HL=データ開始アドレス、BC=データ長
_loop:
	ld      a, (hl)		;8
	ld	d, a		;5
	and	a, #0xf0	;8
	rra			;5
	rra			;5
	rra			;5
	rra			;5
	; output high nibble
	out     (#0xa1), a	;13 -> 54 (a)
	call	_wait	 	;18 + _wait
	inc	hl		;7
	dec     bc		;7
	ld	a, d		;5
	and	a, #0x0f	;8
	; dummy
	inc	hl		;7
	dec	hl		;7
	ld	d, #1		;8
	ld	d, #1		;8
	nop			;5
	; output low nibble
	out     (#0xa1), a	;13 -> 75 (b)
	call	_wait	 	;18 + _wait
	ld      a, b		;5
	or      c		;5
	jp      nz, _loop	;11 -> 21 (c)
	; 終了処理(省略)

_wait:
   	ld      e, #24		;8
_wait_loop:			; 16 per loop
	dec	e		;5
	jp      nz, _wait_loop	;11
	ret			;11
  

ニーモニックのあとに表記しているのは実行クロックです。 M1 waitおよびI/O waitを考慮した数値です。 CB/DD/ED/FD修飾のある命令は存在せず、すべてRAM上で実行させるので、これ以外のウェイトは入らないと思います。

元データを壊してもいいならrldを使えばもっと高速になったりしますが、今回は単に実験なのであまり深く考えず、上位/下位のそれぞれが同じ時間で再生されるようにします。 同じwaitルーチンを使うために、処理の速いlow nibbleはダミーを入れています。 これで

  high nibble = (a) + (c) + wait(w/ call) = 75 + wait(w/ call)
   low nibble = (b) +       wait(w/ call) = 75 + wait(w/ call)
  

と、同じ時間で処理できます。

これだと高速すぎるので、waitルーチン内においてeレジスタの設定値で時間調整をします。 クロック周波数3993600Hzで8000Hzの再生をするためには、 1サンプルあたり、

  3993600 / 8000 = 499.2
  

となり、ひとつのサンプルがおよそ499クロックになるようにウェイト時間を調整すればいいことがわかります。 callに18クロック、ウェイトのループ以外の処理に19クロック、ループ1回に16クロックなので、逆算すると、

  (499.2 - (75 + 18 + 19)) / 16 = 24.2
  

となり、eレジスタの値を24にしています。

これを再生させると、7.25秒分のサンプルの再生に実測でおよそ11秒かかってしまいます。 当然音程も低くなります。

ひとつのサンプルにかける時間を350クロック程度にすると、おおよそ原音に近い時間と音程になります。 なぜでしょうね...??

実験はエミュレータ(PC-6001VW ver 205c)で行いました。 いま分解ですごいことになっているので、実機では試験できていません。