雑記帳

電子計算機の"明後日"から、他愛もない話まで。

Intel Galileoボードが生産終了予定らしい

突然ですが、こんなニュースを目撃してしまいました…。

https://twitter.com/YusukeOhara/status/876827794600275969
https://hardware.srad.jp/story/17/06/21/0628234/

なんでも、Intel Galileo(含Gen2)、Edison、Jouleの各ボードが、今年一杯で生産終了とのことです。

ちょっと待って…。オレ、Galileo Gen2向けにOS書いてる最中なんだけど…。

いや、正確に言うと、モジュール間通信仕様(って言えば良いのか、或いはオブジェクトシステム仕様といえば良いのか、とにかくこのOSの核となるI/F部分)を固める為に、まだWindows上で動くシミュレータをスクラップ&ビルドしているところなので、カーネルやドライバが直接影響を受けた訳ではないのですが、このシステムのテーマとして「ソフト・ハードを問わないモジュール実装と高いモジュール可換性を実現する」と掲げているだけに、手軽にGPIO操作できるターゲットボードが無くなってしまうと、正直ファーストインパクト半減といったところです…。まぁカーネルそのものはGalileoPC/AT(IA-32)版で共通にするつもりだったので、Galileo固有のドライバをオマケで準備する程度には対応するつもりですけど…なんだかなぁ。

正直、(チップ単体と違って)民生品っぽいとはいえ組み込み分野の製品ですので、細々と長期生産してくれるものだと勝手に考えていたのですがねぇ…。下手すりゃそこら辺の市販マザボとかよりも短命だったんじゃなかろうかという気がします(特にJoule)。

尚、今回はチップそのものがディスコンになる訳ではないように見えるので(先行きはあまり明るくない気がしますが)、またQuark X1000を使ったボードとか出てくれればいいなぁ…と、生温かく期待することにしておきます…。

 

ええと、ついでにOSネタの進捗状況です(長らく外部に見える成果が出てないので、何かこういう形でも出さないと寂しい気がしてきました…)。

上の方で少し書いた通り、まだ仕様固めに走っている段階で、カーネルにはほとんど手が入っていません。最初はカーネル上で色々試行錯誤していたのですが、一旦メモリ管理のことを忘れたくなったので、Windows上で動くシミュレータを作り、そっちで実験することで試行錯誤を高速化することにしました。お蔭でI/Fは大分目標地点に近づいてきたと思います(アプリ走らすところまで確認できたら一旦完成にして、カーネル上への移植を始めようかと)。

このシミュレータですが、いずれ実OSが走っているマシンと通信してなんやかんやするツール(デバッガ兼ウィンドウマネージャ…Xサーバみたいな…)を作るつもりだったので、実験完了後はこっちの雛型にでもして、無駄にしないつもりです(笑)。

しかしまぁ、このシステムの本丸に定めているアイディアは4~5年位前に思いついたものなのですが、これをベースに「オペレーティングシステム」として使いものになるよう細部を詰めていくと、なかなか一発で良い形にはなりません。最初の頃は、無駄に使い勝手が複雑だったり実用アプリが書き辛い仕組みになってしまったりと(実は1回だけ人目に触れた機会があるのですが、そのころの話です)、せっかくのネタが生きない代物になってしまったので、実際にテストアプリを作りながらフィードバックしたり、「最終的に同じことが実現できるものの、全く別なI/Fやオブジェクト機構」を考え直して大改造するとか、ここ2~3年はこんなことばっかりやっております。これもやっと、Windows上で検討サイクルを高速化(ぉ)したことで終わりが見えてきたところですが…。

ということで、まだまだ時間はかかりそうですが、Galileoディスコンまでに実機で動く版をリリースできればいいなぁ…とぼんやり考えながら、引き続き開発を続けようと思います。つーか早くこのシステムで動くアプリを書きたい(順番

尚、実際に動くところまで作ってみたら大凡実用的とは言えない何かになる可能性もありますが、それはご愛嬌ということで…。

親指の友 Mk-2ドライバと、フリーソフト作者としてのスタンス(2017/6/21追記有)

また、ブログの方は暫く間が空いてしまいました(メインサイトの方は若干更新しましたが)。

ここのところ、掲示板の方によく「親指の友 Mk-2」ドライバ絡みの質問などを頂くことが増えてきました。増えてきた…ということは、何らかの理由で以前よりも人目に触れる機会が増えたのではないかと思ったのですが、調べてみると、どうやらいつのまにか、親指シフトの総本山たるNICOLAのサイトからリンクが張られていたようです。

勿論、自分が作ったものを多くの方に使っていただけるようになったというのは作り手冥利に尽きる事ではあるのですが、このドライバに限っては、以前よりも遥かに見つかりやすくなってしまったことで少々困惑している節があります。

というのも、親指シフターというのは、どちらかというとあまりPCに詳しくない方が一定数含まれるらしい集団である…というのが昔からの印象でして、この中にはメーカのサポートセンターだったりの常連さんも居るのでは? という偏見があるからです。つまり、「フリーソフト作者に対しても同じ感覚で来る方が現れたらどうしよう…」ということです。

 


(2017/6/21追記)

特に本ドライバのx64版は、導入時にオレオレ証明書を作ったりcatファイルに署名したりと、大凡ドライバ開発者が仕事でやるような作業を各自行わなければいけません(DSEO等で代用する場合を除く)。ここまで厄介な導入手順を踏む代物でなければわざわざ前述のような懸念をする必要などなかったのですが、M$の署名ポリシーを安全側に汲むと、これ以上簡単にすることは断念せざるを得ませんでした(現状でさえ、それなりにリスクを伴う方法ですが…)。

幸い、私以外にも導入方法について解説する記事を書いて下さった方がいらっしゃるので、(私が書いたReadmeしか資料がない状態よりは)遥かに敷居が下がっているとは思いますが、それでも、インストーラー付きアプリの導入なんかに比べればとても複雑な作業です。

元々このドライバは、「親指シフトをコードの読み書きをする人にも使ってほしい」という意図がありまして、そういう人達が使ったり、或いは気に入らないところを改造したりすることで、ドライバや実装方式、親指シフトの仕組みそのものの改良・発展が進んでいけば良いのではないかと考えていました(そうなってくれば、親指シフト界隈も多少盛り上がるのではないかという期待を含めて)。そういったこともあって、(どうせ利用者がソース弄るんだろうから)x64版の署名はWDKのツールを使うなりして各自でなんとかすれば良いんじゃないかと考えていた節もあります。

なので、本来利用者として想定していない方々(例えば、先の導入方法の記事を読んでも、いまいちピンとこないような方)が流入してしまったとしたら、もしかするとお互いにとって不幸なことなのかもしれません…。


 

ということで、自己防衛の為にも、改めて一言書いておこうと思います(DLページのところにも少し追記しておきました)。このサイトで公開しているソフトウェアはいずれもフリーソフトであって、使用許諾の条件として、使用者の方には「自己責任の下に使用すること」を要求しています(readme.txtを参照下さい)。つまり、市販されているような製品(Japanist等)と異なり、私が使用者の方をサポートする義務はありません(法的にも倫理的にも)。

このサイトで公開しているソフトは全て趣味の成果物です。とりあえず作ってみたけど、もしかしたら他にも使ってくれる人がいるかもしれない…と思って公開している代物です。私は「アイディアを思いついて形にしてみる」ところまでが好きなのであって、事細かに説明書を書いたり、サポートセンターみたいなことをしたりするのは趣味ではありません(勿論、仕事として受けている範疇であればやりますけど、でもこのドライバは仕事で作ったものではないので)。

このため、本ドライバをお使いになる場合は、基本的に「何があっても(例え上手く動かなくても)ご自分で対処する(場合によってはあきらめる)」前提でご利用下さい。勿論、バグレポートや技術的な質問等についてはこれまで通り歓迎しますので、こういった話があれば掲示板にご連絡頂けると助かります。

 

ちなみに、以前の記事にも書きましたが、私としては今後、キーボード関係(親指シフト関係を含む)で新しく何かを作る予定はありません。

また、私は親指シフトを使いたい以前に、Windows環境下で「富士通製の板バネメカニカルキーボード」を使いたい人なのであって、これらを満たすことがないような話に対して自発的に動くことはありません(仕事であれば別ですが)。

勿論、またWindowsのバージョンアップに伴ってドライバが使い物にならなくなった…といった事態になったら何か対策することを考えますけど、年々野良ドライバに対するハードルが上がっているので、恐らく次に手を入れる時は「ドライバ」という形態を捨てることになるのでは…という気がしています。

現時点でわかっていることとして、

  • キーボードレイアウトファイルについては、x64 + 非テストモード環境に於いても未署名バイナリのままロード出来ることを確認済(初期のWin10にて)
    • そもそもユーザモードDLLなので、セキュアブートとかの対象にもならないはずですし
    • 基本的に定数テーブルを参照させる為だけの存在なので、ドライバ本体と違って悪さできる可能性がない点も重要です
      • よって、このファイルは、今後も個人製作のものが使える可能性が高い
  • 親指の友 Mk-2ドライバの本体側で行っている親指シフトの制御ロジックは、キーボード側で行ってもシステムとして成立する仕組みになっている
    • 同時打鍵操作を逐次シフトのパターンに変換しているだけなので
    • 常に同時打鍵監視のロジックを動かすことができるので、モードずれの心配も無ければ、モード同期の為の制御をPC本体側から行う必要もない
    • さらに、零遅延モードがあるので、英字入力時にもたつく心配もない

ということで、最終的には

  • OyayusbyにMk-2ドライバ相当の同時打鍵監視ロジックを入れる
  • Mk-2ドライバのレイアウトファイルのみを、上記Oyayusby向けに改造

といった2本立てみたいな形で落ち着くんじゃないかと考えています。

勿論、上記のどちらもソースを公開していますので、喫緊に必要としている方がいらっしゃれば、私に代わって実装して頂いても良いですし、むしろその方が有り難いです。寧ろそうなることを期待しています。

USB-DAC for STM32F4 Discovery

ええと、前回分が長くなりすぎましたので、改めて本題です。

早速軽いのを作ってみました。USB-DAC for STM32F4 Discoveryです。

イメージ 1

というのも、メイン機のSE-90PCIが絶不調(ボード差しているとよく死ぬ)になってしまいまして、急遽代替品が必要になったからです。たまたま、以前勤めていた会社から「自己啓発用」として渡されたボードが余っていたので、こいつを使ってサクっと(はいきませんでしたが…後述)作ってみました。

一応、このボード上にはDAC(CS43L22)が乗っていまして、こいつを使って音声出力しています。データフォーマットはPCM 44.1KHz 32bit ステレオ固定です(但し、DAC側は24bitまでの対応なので、I2S送信時に最下位8bitは無視されます)。また、ストリームの転送にはアイソクロナス転送の非同期モードを使用します(DACをホストと独立したクロックで動かし、別途フィードバック通知用のエンドポイントを用いてホストからの送信データ長を調整します)。Windows Vista以降であれば標準ドライバで使用できるはずです。

今回から、ブツのアップ先をgithubにしてみました。また、ファーム書き込みに開発環境が必要なので、生成済のバイナリは用意していません。試してみたい方は"System Workbench for STM32"を導入の上、リポジトリのプロジェクトをインポートしてビルド→デバッグ(書き込み)を行って下さい。他、動作中のLEDに関する説明や、micro-B側からのバスパワー化改造等については、リポジトリの方のreadmeを参照下さい。そもそも英語でまとまった文章を書いたのがほぼ初みたいなものなので、あんまり酷いところや意味不明な文などがありましたらご指摘頂けると幸いです。

本当はサンプリングレート・ビットレート等を色々選べるようにしようと思ったのですが、チップのデータシートを見れば見るほど微妙な気がしてきたので、この石を使って全力で作るのは止めました。というのも、まずチップ内蔵のUSB Phyがフルスピードまでにしか対応していないため、データレートを上げるのは困難です(1023バイト/msまでしか転送できないため、176.4kHz 24bit ステレオがギリギリアウトとなる)。また、DACへのMCLK出力を有効化すると、一般的な帯域における実サンプリングレートでそこそこの誤差が出ます。CS43L22はMCLKを入力しないと使えないDACのため、止むなく44.1kHzのストリームを約44.108kHzで再生する実装としています。幸いフィードバック通知用のエンドポイントを使っていますので、こんな誤差持ちでもデータバッファが空になったりすることはありません(長時間演奏でもおかしくなることはないはずです)。

また、プロジェクトの雛型自体はCubeMXで吐かせたものを使っているのですが、USB Audioスタックがそのままだとまるで使い物にならなかったので、それなりに手を加えております。他、USBコアやI2Sドライバにも手を入れています。

特に、このチップのアイソクロナス転送機能は、送受信開始時に予め「奇数フレーム / 偶数フレームのどちらで転送すべきか」を適切に指定する必要があります。ドライバの素の実装では、送受信開始時点で最後に受信したSOFのフレームIDを見て、次のフレームで正しく転送が行われるようビットを設定しているのですが、そもそも次のフレームで転送が行われるかどうかはホスト次第ですし、再生停止中(ホストがSET_INTERFACEでalt = 0を選択している状態)はOUT転送が全く行われません。さらに、フィードバック用のエンドポイントはディスクリプタに記載された周期(今回は32ms毎)でしかIN転送リクエストが来ませんので、タイミングによってはフィードバック送信が全く行えなったり、初回のデータストリームを取りこぼす可能性があります。

元のプロトコルスタックではこの辺りに対するケアが全く無く、このままだと全く使い物にならないのですが、データシートをよく見ると「アイソクロナス転送のincomplete割り込み」というのがありまして、SOF~一定時刻までに予定したアイソクロナス転送が行われなかった場合に割り込みを起こすことができます(但し、素のプロトコルスタックでは、このコールバック関数の呼出パスが突然分断されてたりする謎仕様です)。この辺を補ったところ、EVEN/ODDの指定を間違えた場合にもこの割り込みが来ているようですので、今回はこれを使って転送をリトライするようにしました(この辺の挙動については、CubeMXの生成物に対するものではありませんが、海外フォーラムなどでは詳しい議論が行われていたりします。最初原因がわからずマジで頭抱えてました…先人達に多謝)。

以上のように、USB-DACという使い方に対しては大変筋が悪い石のような気がしますので、わざわざこのボードを買ってきてまで作るようなもんではないと思います。が、もし手元にSTM32F4 Discoveryが使い道も無く余っているようでしたら、こういった形で復活させてみるのも良いと思います。

あ、ちなみに音はそんなに悪いもんじゃないですよ。直接ミニフォーンジャックにヘッドホンを差して聞いても、特に目立ったノイズは感じません。自前のアンプ + SX-WD5KTに繋いでみても、今までのSE-90PCI(DACからの直出し)と比べて、一聴してわかるほどの悪化は感じられません(少なくとも、良くなった印象はありません)。まぁこんなもんか…という感じです。

でもまぁ、そのうちハイスピード対応の石と差動出力対応のDACを使ってちゃんと作りたいですねぇ(秋月のラインナップだとNXPのLPC4337位しか無いなぁ…)。

 

もしこのコードをベースに色々弄る場合は、以下にご留意下さい。

  • ディスクリプタを弄る場合、同一VID/PIDのデバイスであればWindowsが初回接続時にキャッシュした値を使ってしまうようです。一旦デバイスマネージャから削除した上で再接続して下さい。
  • ビルドオプションにて、最適化レベルを「デバッグ(-Og)」にしています。-O2(デフォルト)等では、ほぼCubeMX生成直後のレベルでも不審死が相次ぎました…。

近況など

また暫く間が空いてしまいました。

 

この間色々ありまして、正直コード書く気力も無くなってたりしたのですが、ふと見たファミコンの解析資料からファミコンプログラミングを始めまして、おかげさまでみるみる回復しました。これめっちゃ楽しいですよ。なんというか、少ない命令とシンプルなハードの組み合わせで何でもやってやろうというのは、プログラミングの面白さの本質に限りなく近いのではないかと思います(最も、HWを省略し過ぎているが故に、一見不可解な動きをされたりしてハマることも多々ありましたが…。資料としてはこちらも見ると良さげです)。まだ暫くは何か公開できるようなものはできないと思いますが、そのうちゲームか何か作ってこっそり乗せるかもしれません。

 

しかし向こう約1年程、クソチップ・クソ環境・クソジジイ達の三連コンボに疲弊しきった身にはこれ以上ない位の回復薬でしたね。もし私のような趣味上がりのソフト屋の方で、タチが悪い方の役所仕事しかできないみみっちい秩序LOVEな連中に囲まれて辟易している方がいらっしゃったら、こういった方向で童心を回復しつつウサ晴らしすると良いのではと思います。そんでもって、千葉の稲毛海岸辺りで夕日に向かって「全部焼け野原になっちまえ! その後立ち上がって次を作り出すことができるのは俺たちだけだ!」とでも叫んでやりましょう(ぇ。

 

さて、こんな状況なので、電脳文庫プロジェクトの方もかなり停滞気味です。いや、全く進展が無い訳ではなく、例えばUEFI用のブートローダを書いたとか(このお蔭で、Intel Galileo Gen2ボードから自前のカーネルをブートできるようになりました)成果が無いこともないのですが、アプリケーション環境におけるリソースや各種モジュール・オブジェクトの表現方法というか見せ方というか、そういったところで良いアイディアが出ず足踏みしている状態です。そこのところに限れば、UnixとかPlan9ファイルシステムって絶妙なバランスだったんですねぇ…とつくづく感じます。決して完璧とは思いませんが。

 

昔、OSASK計画の川合さんから例の緑本(と、カオちゃんのバンダナ!)を頂いて以来、長らくOSの研究的なことを趣味でこっそり続けてきたのですけど、post Unix世代とでも呼べるものがなかなか世に広まらない理由って結局この辺なのかなと思います。単純に、手持ちの環境で動くOSと呼べるものを作り、その上で走るアプリを用意して見せるだけなら、例の緑本で川合さんが示したようにそこまで難しい話ではないはずです(実際、海外フォーラムとかでも多くのプロジェクトを見かけられますし)。ただ「多くの人に使ってもらえるような良くできたアプリケーションプラットフォームを作る」となると別問題なだけで。なので、結局多くのOSプロジェクトは、例え革新的な設計だったとしても「POSIX準拠のユーザランド載せました☆」とか言い出しちゃって、折角「そのOSを使うことでできる面白いこと」があっても殆どユーザランドから使えず(使えたとしてもベンチ結果がちょっと良くなったとか、メンテ性向上とか)、「別にLinuxで良くね?」 or 「一部機能だけLinuxにマージ」という流れに行き着いてしまうのではないでしょうか(主にマイクロカーネル勢の瓦礫の山を横目に見ながら)。

 

尤も、ただアプリケーションを走らせるだけならば、抽象化レイヤを積み重ねていくことで下層レイヤのことなどいくらでも忘れられるので(ぇ)、単純にもっと新しい設計のプラットフォームを求める人たちの多くは、より上層に新世界を積み重ねていくことで理想を実現する方向に移って行った…というだけのことかもしれません。

 

しかし、ハードウェアと密に組んで何か面白い物を作ろうとするとそうはいきません。当たり前ですけど、「生まれたてのHW」みたいな抽象化されたこともないようなのが出てきたとき、こいつを上層から扱おうとするには、最下層に降りてデバドラ作るところから、最悪はAPIやらもっと上位のラッパまで用意してやらないといけなかったりします。
まぁLinuxだったら、デバドラから見せるI/Fを上手くファイルアクセス(read/write)として表現できる場合に限り、上層から触るハードルが随分低くなるのでまだマシなのですが(例えば、Intel Galileoだと、/sys/class/以下のファイルにアクセスすることで諸々のI/O操作が行えるようになっているそうです)、それでもデバドラの開発とI/F上の制約が付きまといますし(割り込みがなぁ…POSIXのシグナル周りはどうもしっくり来ない記憶が…)、そもそも文字列ベースのデータのやりとりは個人的に嫌いなので、この辺何とかしたいところです。

 

こういったように、電脳文庫の場合、ソフトウェアプラットフォームとしての既存OS(特にPOSIX環境)に不満を感じた上での新規開発なので、(一番問題と考えている)モジュール間I/F部分の改良が要となる訳です。他にももっと野心的な試みを内に秘めていたりもするのですが、最低限ここだけは妥協ができません。通信の仕組みそのものについてはかなり前から固まっているだけに、あとは上手いモジュール表現の方法が固まればなぁ…というところです。たかがコード書き歴20年弱程度だと、まだまだ思うようなモノを作れないもんだと痛感しますね…。

 

このため、しばらく(何かブレイクスルーがあるまで)はこちらを止めて、何か気分転換になるような軽いものを作るのが続くかと思います。

 

本当はここまでマクラのつもりだったのですが、長くなったので本文にしようと思った話は改めて書きます(ぇ。

Windows 10を「本物の」クラシック表示で使う

また暫く時間が空いてしまいました。

この間、7月末に駆け込みでWindows7→10への無償アップグレードを済ませたのですが、Windows 95 日本語β版以来あの操作環境に慣れ切ってきた身としては、ビジュアル面が大きく変わったせいかあんまり表示が頭に入ってこない感じになってしまって、ちょっと使いづらくなってしまいました。

無理やり以前の環境に近づけようとする場合、例えばExplorerの使い勝手については「秀丸ファイラーClassic」を使えばほぼXP相当にできますし、アイコンデザイン変更に伴う違和感(というか認知の遅れ)は、昔のデザインのものをWin95のインストールディスク等から回収してレジストリ上で差し替えてやることで解消できます(この2つをやるだけでも結構効果的です)。しかし、7まではあったUIのクラシック表示がWindows 8以降は廃止になってしまったため、そのままではこれ以上以前の使い勝手に戻すことができなくなってしまいました。

どうにかならんものか…と色々調べてみたところ、英語圏のフォーラムではWindows 8登場時からそいういった模索が行われていたようで、少々ダーティですがクラシック表示を可能にする方法が確立されていました。しかし、どうもまだ日本語圏ではそういった情報が見られませんので、自分自身のメモがてら、まとめを書いてみたいと思います。

尚、日本でもテーマを無理やり繕って「クラシック風」のデザインにする「クリーン」な話はちらほら見かけるのですが、そういったレベルの話ではありませんのでご安心を;-)

 

操作手順の参照元は以下になります。

http://www.msfn.org/board/topic/173367-simple-hack-enables-classic-theme-in-windows-10-and-8-too/

動作原理については、以下の2つのページが参考になります。

http://forum.thinkpads.com/viewtopic.php?p=745259#p745259
https://thisissecurity.net/2014/04/08/how-to-run-userland-code-from-the-kernel-on-windows/

ざっくり要約すると、テーマが有効になっている環境(Win10では必ず有効になります)では、GUIを持つアプリの起動時にwin32k.sysによってUxTheme.dllがユーザモードへ突っ込まれるのですが、この際にWinLogon.exeが作成した"ThemeSection"なる名前を持つハンドルを使って使用するテーマの情報を得るようです。その後、これを元にUxTheme.dllがUIの描画を担います。
ここで、このハンドルを外部から無理やりクローズすることでテーマの参照ができないようにしてしまうと、UxTheme.dllによる描画を諦め、これまでと同じWin32k.sys内のクラシック表示用ルーチンを動作させることができます(というか、こっちのコードは残っていたんですねぇ…。もしかしたらフェイルセーフ用かもしれませんが)。これを利用することで、無理やりクラシック側のコードしか走らないようにしてしまうのが今回の主旨です。これなら今までと同等のビジュアルになるだけでなく、描画そのものをカーネルモードで行わせることになるので若干のパフォーマンス改善にも繋がるかもしれません。

 

では実際にハンドルのクローズを行う方法ですが、コマンドラインからハンドル操作を行うソフトとしてSysInternalsのHandleがありますので、あとはこれを使って上記ハンドルを閉じるバッチファイルでも作ればOKです。

参照元のページにはCamTron氏が投稿したバッチファイルが貼ってあるのですが、ログインしないと読めないようですので、他の方が転載したと思われる代物(ここ)を元に、正しく動くよう修正したものを以下に置いておきます。

@echo off
FOR /F "delims=^T" %%G IN ('Handle ThemeSection') do set output=%%G
FOR /F "tokens=6" %%G IN ('echo %output%') DO set handleid=%%G
FOR /F "tokens=3" %%G IN ('echo %output%') DO set pid=%%G
echo %handleid%
echo %pid%
Handle -c %handleid% -p %pid% -y

このバッチファイルをHandle.exeへパスを通した環境で管理者として実行すると、これ以降に起動したアプリは全てクラシック表示となります。
ここで行っている操作はサインアウトすれば元に戻りますので、恒久的にクラシック表示にしてしまいたいのであれば、タスクスケジューラを使ってこのバッチファイルをログイン時に実行するよう登録しておくと良いです。尚、「最上位の特権で実行する」のチェックと、バッチファイルのカレントディレクトリは忘れず登録して下さい。

 

ちなみに、無理やり動かしているだけあっていくつか不具合がありまして、

  • なぜかメニュー表示がフラットスタイルになります。
  • 前述の方法では、起動タイミングの都合上、Explorerに対してクラシックスタイルを適用することができません。
  • だからといってExplorerを一旦落として再起動させると、クラシックスタイルにはなりますが、タスクバーや右クリックメニュー等の表示が崩壊します(使い物になりません)。
  • コントロールパネルからテーマに関連する設定を開くことができなくなります。例えば「個人設定」や「コンピューターの簡単操作センター」など。
  • なぜかタスクマネージャが即死するようになります。但し、これについては、タスクマネージャをSysInternalsの「Process Explorer」に置き換えるなどしていれば影響を受けません。
  • ストアアプリが上手く動かなくなります(例えば、「設定」であれば、歯車が表示されてから先に進まなくなる)。
    Windows8以降は電卓もストアアプリになってしまったので致命的なのですが、電卓だけなら、MS謹製の「Calculator Plus」を入れれば使い勝手が大きく変わることもなく回避可能です。
  • Win7であればAeroGlassが効いていたであろう領域が半透明になります(Presto時代のOpera(v12.18)のタイトルバー等)。

これらの現象が問題となる場合は、タスクスケジューラからバッチのログイン時実行を一時的に消し、一旦サインアウトしてしまえば良いでしょう。

 

本当は、別のところで公開されている"ClassicTheme"というソフトを使った方が、上記クラシック表示に伴うトラブルを解決する為の処理を一部やってくれる為便利なのですが、困ったことにWindowsDefenderがマルウェア扱いしてくるので、ソースを読んで何をやっているか理解できる方以外にはおすすめしません。

 

一応これでクラシック表示は実現できたのですが、Win10のデフォルトではタイトルバーの幅などがWindows 95以来のデフォルト値より大きく設定されています(テーマ適用時と共通の値が使われますので、そちらに合わせたサイズになっています)。こちらは以下のレジストリキー以下を弄ることで変更可能です。

HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics

座標系の単位はいずれもTwip(.netになる前のVB使いだった方にとっては鼻水が出る程懐かしいのでは…)のようでして、96dpiの環境では15で1ピクセルです。参考までに、こちらで設定した値を以下に載せておきます。

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics]
"BorderWidth"="-15"
"CaptionHeight"="-270"
"CaptionWidth"="-270"
"MenuHeight"="-270"
"MenuWidth"="-270"
"ScrollHeight"="-240"
"ScrollWidth"="-240"
"SmCaptionHeight"="-210"
"SmCaptionWidth"="-210"
"PaddedBorderWidth"="0"

デフォルトへ戻したい場合は以下に設定して下さい。

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics]
"BorderWidth"="-15"
"CaptionHeight"="-330"
"CaptionWidth"="-330"
"MenuHeight"="-285"
"MenuWidth"="-285"
"ScrollHeight"="-255"
"ScrollWidth"="-255"
"SmCaptionHeight"="-330"
"SmCaptionWidth"="-330"
"PaddedBorderWidth"="-60"

 

フォントについては同じキー配下にあるCaptionFont、IconFont等を弄れば変更できます。バイナリなので一瞬面食らいますが、GDIで使われるLOGFONT型(Unicode版)のメモリイメージのようです。詳しくはMSDN等を参照下さい。

色についても、昔と同じレジストリキーから設定できます。お好みのカラーリングを設定してみて下さい。

HKEY_CURRENT_USER\Control Panel\Colors

 

ここまでやると、こんな表示に持っていくことができました。

イメージ 1

 

前述のような不具合もありますので100%実用的かと言えば微妙ですが、上手く切替ながら使えば、違和感を抑えつつ作業効率を上げることが可能ではないかと思います。尚、ここに記載の内容を使った結果、未知の不具合やトラブルに見舞われる可能性もありますので、くれぐれも自己責任の上、参考にして頂ければと思います。

"呪い"の、キーボードマイコン

事の発端

学生の頃にH8マイコン基板を使ってFMR(TOWNS)/OASYS用キーボードをPS/2に変換するアダプタを作って以来、そのリニューアル版にあたる「FMR to PS/2 キーボード変換器」に移行しつつも、長らくFMR60KB201(初代FMR-50/60/70系の親指シフトキーボード)とFACOM6140KA1(88年モデルからのOASYS-100系親指シフトキーボード)をメインキーボードとして使ってきたのですが、一貫して一つの不満がありました。

「なんとなく反応が鈍い(気がする)」

全般的にどのキーに対しても言えることではあったのですが、特にカーソルキーを派手に使ったりした場合は露骨で、ギリギリ許容できる範囲でありつつ、確実にやる気を削ぐ絶妙な遅延がずっと気になっていました。

カーソル操作といえば、FMR系のキーボードはこれらのキー操作に限って、なぜか無駄にインテリジェントな通知をして来ます。こういったことから、変換アダプタの方でキー解析に時間がかかっているせいでトロく感じるのではないか? と考え、今のFMR to PS/2 キーボード変換器に至るまで高速化を目指して改良してきた訳です。

しかしながら、

  • カーソルキーの解析は200μsもかからず実行できている(実測)
  • キーコード2バイト目受信完了~PS/2側送信完了までの実測は約2ms程度(PS/2側0xE0プリフィクス付きの場合)

という状況まで追い込んだところで件の遅延が体感上改善しないことから、

「遅延を生み出している張本人はキーボードに乗っているマイコン / 通信プロトコルではなかろうか」

という疑惑が生まれました。

 

そもそも、キーボードからの通信仕様を眺めたり、実際に信号を観察したりすると、

  • ボーレートが9600bpsと、PS/2での最速通信速度(約16.6kbps)の約半分程度
  • 2バイト目のデータを受信しないとキーコードが得られない(1バイト目はフラグ類なので)
  • しかも、1バイト送信毎に約4.5ms程の間隔を空けて送って来る
  • 全キーのマトリクススキャン自体に16msかかっている

という素敵な設計になっており、既にこの時点で変換器よりも遥かに大きな遅延が生み出されています*1

プロトコルやキーボードマイコンの問題となると、さすがに外からはどうしようもないので途方に暮れていた訳ですが、親指の友 Mk-2ドライバに零遅延モードを追加する実験等を通して、益々キー操作の応答性を意識するようになったところで、さすがになんとかしたいと考えていた矢先、重要な存在を思い出しました。

 

FACOM6130KF1

イメージ 1

こちらもOASYS-100系親指シフトキーボードなのですが、FACOM6140KA1よりも前のモデルです。

神田さんのところのカタログやビジネスOASYSの型番・製造時期を見る限り、86年の100F2や、87年モデルの100HX・100N辺りで使われたのではないかと推測されます。

何が重要かと言うと、このキーボード、エンコード用のマイコンが乗っておらず、標準ロジックICで組まれた行列選択回路を直接外部から叩けるI/Fになっています。ようは「直接キーマトリクススキャンをしてください」ということですね。もし件の遅延がプロトコルマイコンのファームに起因しているのであれば、このキーボード用の変換アダプタを作った際には遅延が発生しなくなるはずです。

 

ということで、早速作ってみました。「OASYS(13ピン) to PS/2 キーボード変換器」です。

イメージ 2

 

本当は「FACOM6130KF1 to PS/2変換器」とすべきなのですが、OASYS-100系用キーボードのうち、他の型番を持つDIN13ピン*2接続のものならキーテーブルさえ見直せば使えるんじゃないかと淡い期待を寄せた為、こういうネーミングになりました。尚、キーボード自体にファントムキー対策(ダイオード)が入っていますので、ソフト的な工夫は一切無くともnキーロールオーバ対応です。

ただ、写真のブツは手持ち部品を使って作った関係上、キーボード基板側のフラットケーブルコネクタ(MIL規格 2.54ピッチ20ピン)から信号線を引き出しており、DIN13コネクタ側の結線については調べてません。ざっと調べてみた限り、こいつのメスコネクタは入手が難しそうだったので(オスの方なら秋葉原のヒロセテクニカルとかにもあったんですが…)、キーボードをOASYS実機に繋ぎかえる必要が無く、かつビジュアルを多少犠牲にしても良ければ、どこでも買えるフラットケーブルコネクタ経由にするのも手かと思います。

 

さて、この変換アダプタを使った結果ですが、結論から言うと非常に良好でして、遅延は殆ど感じられず、丸5年を経てやっと普通のキーボード生活に戻れたような感じです。これならキーを押す度にやる気を削がれることもありません。

以上の結果より、やはり遅延の主たる原因は、キーボードマイコン(か、通信プロトコル)にあったと言えそうです。

 

話の続き

個人的な問題として、とりあえずOASYS配列のキーボードについては、FACOM6140KA1に代わってFACOM6130KF1を使うことで遅延問題は解決しました。

しかし、FMR系の配列を持つキーボードはいずれもマイコン内蔵になるため、こっちの配列で使えるキーボードが無くなってしまいます…。最悪、パターンカットして元々のキーボードマイコンを切り離し、マトリクススキャン版の自作アダプタを仕込む作戦が考えられますが、我が家ではFM-TOWNSが現役であり、キーボードをこちらに繋いで使う場面があるため、元のマイコンを使えなくするのは抵抗があります…。

ということで、こんな仕組みを考えてみました。

 

パラサイトキーボードマイコン

ようは、マイコンからマトリクスに対する出力が衝突しなければ(Hi-Z固定にさえなってくれれば)、追加マイコン側からの走査出力が繋がっていても影響はない訳です(逆に、元マイコンに走査させる場合は、追加マイコン側の出力線を入力ポートに設定すればOKです)。

ということで、2つのキースキャンマイコンを同居させ、接続状況に応じていずれか一方のマイコンだけがマトリクススキャンを行うような構成を組んでみました。元マイコン側が動作すれば今まで通りですし、追加マイコン側が動けば高速なPS/2キーボードに早変わり…という訳です。

FMR/TOWNSシリーズのキーボードマイコンにはi8049(又はそのCMOS版であるi80C49)が使われており、マトリクススキャン用の線はこれのバスポート(DB0~6又は7)に繋がっています。このポートは名前から推測できるように、丁度初期出力がHi-Zになっています。よって、追加マイコン側から元マイコンのリセットピンを制御すれば、元マイコンのキースキャンを制御できる…ということになります。

接続先の判断についても、FMR側ではキーボードからのTx線がオープンコレクタ出力になっており、受信端でプルアップするようになっています。よって、プルアップの有無(予め高抵抗でプルダウンしておき、アイドル時電位のH/L)を判断すれば、FMR側が接続されているのかの判断は可能です。

 

以上のことより、起動時にこの信号状態を見て、i8049側のリセットを制御する機能を「OASYS(13ピン) to PS/2 キーボード変換器」に追加してしまえば、当初の目的を達成することができます。というわけで、早速組み込んでみました。

イメージ 3

 

こちらを使ってみた結果ですが、やはり大変良好で、いかにタッチの好みを遅延で相殺していたか思い知りました。先月からブログの更新ペースが上がっているのですが、冗談抜きにこのアダプタを作ったことで遅延問題が解決したことが原因です。だって、よくよく考えたら超好みのキーボードだったはずなのに、今まで家帰ってから全然触る気がしなかったんだもんなぁ。今の反応であれば時間が許す限り触っていたいので、そりゃアウトプットも増えますよね。

 

尚、こちらの機能も「OASYS(13ピン) to PS/2 キーボード変換器」の公開版に含まれていますが、あくまでもオマケ機能であり、デフォルトは無効にしています(ソース中のコメントを外してリビルドする必要があります)。また、(完成して暫く使ってから気付いたのですが)PAUSEキーやEXT1キー等が増えているタイプ(FMR60KB211)ではマトリクスの制御線が1本増えているため、これらのキーボードを使う場合はアダプタとの接続やファームの制御を一部変更する必要があります。

 

しまいに

さて、自分としては、大昔にFMR60KB101を触ったことで始まった「キーボード熱」が、紆余曲折を経てやっと満足いく着地点にたどり着いたかな…というところです。我ながら大変長い脱線だったと思いますが、これでようやっと、快適な環境で集中して「作りたいものを作る」作業に戻ることができます*3

ということで、もし期待して頂いていた方が居られたら申し訳ないのですが、今後キーボード周りのハード製作やソフト・資料の更新を行う予定はありません。勿論、(今回のように)突発的に何か思いついて、急遽作ったりチューニングしたりということはあるかもしれませんが、基本的には新規で何か作ったりすることはないとお考えください。

一応こちらの製作物は全てソースコードを同封してありますので、必要な機能が欲しい方は、是非ご自分で改造するなりして対応して下さい。

 

この記事までで、とりあえずブログ用に書こうと思っていたネタも消費したので、今後は電脳文庫プロジェクトの開発を進めつつ、ブログの方にはそっちに関連するネタ(OS設計に関するネタ、関係するハードのネタとか)や作り事全般に関する話を書いていこうかと思います。

 

オチ

ノロいの、キーボードマイコン…。

…うん、つまらん。

 

まぁやる気削ぐって意味では立派な呪いでしたがね。

*1:でも、TOWNSに繋いで使っているときは、そんなにトロくは感じないんだよなぁ…。
そもそもシステム全体がトロいから気にならないだけなのか、ソフト側のステップ数やハードの経路段数が少ない分、割り込み応答性がV機よりも良いのか…。

*2:ACOM6130KF1入手当時に調べた際、「これはDIN13ピンと呼ぶらしい(呼ばれているらしい)」と判断したため、以降この名前で呼んできたのですが、実はDIN規格とは関係ないコネクタのようで(DIN規格は8ピンまでしかない)、正しくはホシデンの丸型多極コネクタ(13ピン)という代物のようです(コネクタにホシデンのロゴが入ってました…)。
まぁ確かに外形はDINコネクタと同じ位ですし、一応世間的にもDIN13ピンで通っているようなので以降もこの名前で呼びますが、お買い求めの際等はお間違えの無いようご注意下さい。

*3:まぁまたPS/2が絶滅する頃に一悶着やるのでしょうが…。でも、USB HIDが現役ならOyayusbyとコレをニコイチするだけですから、はっきりいって大した作業じゃないですねぇ。

電力アンプ再び(バランス入出力)

以前、「電力アンプ」なるものを紹介しました。

以来、あの系統のアンプを使っているのですが、現在私が使っているのは以下のような構成です。

 
(負荷に日本ビクター SX-WD5KTを繋ぐ場合)
イメージ 1
 
(負荷にPARC Audio DCU-F071Wを繋ぐ場合)
イメージ 2
 
上記記事でも触れた通り、発案者の方が「個人利用に限定され、著作権者の許可なく商用利用できません」として公表されているアイディアをベースにしていますので、こちらも同様の取り扱いをお願いいたします。

 

一番大きな変更点は入出力共に平衡回路化したところです。これによって、仮想GNDにL/RChの信号電流が流れ込むことがなくなりますので、クロストークの大幅な改善が期待できます。また、仮想GNDの安定化に心血を注ぐ必要もありません(フラつく要因がありませんので、適当に抵抗で分圧しておけばOKとなります)。

また、出力電流が稼げるタイプのオペアンプ(AD8397)に変え、直接低インピーダンスの負荷をドライブさせるようにしてみました。元回路のままだと検流抵抗の値が小さくなりすぎてしまうので、(出力は幾分か落ちますが)検流抵抗自身で公称インピーダンス近傍となる帯域でのマッチングを取り、正帰還は補助的に使う形へ変更しています。尚、正帰還をかけている部分の回路を取っ払うと、ただ公称インピーダンスでマッチングを取っただけの電圧出力アンプになります。

AD8397のデータシートを見ると、5V駆動した際のピーク出力電流は230mAとありますので、6Ω負荷で最大317mW程度の出力となります。こう書くと音が小さすぎて使い物にならない気がしそうですが、例えば87dB/W/mのスピーカであれば上記出力での1m先での音圧は約82dBとなります。昼間の静かな室内での騒音が約50dB位と言われていますので、これだけの音圧が得られれば家庭で音楽を聴く分には十分過ぎるのではないかと思います(まぁ防音のリスニングルームとか持っている方なら別でしょうけど)。

 

当初は元回路と同様、正帰還を抵抗1本で済ますようにしていたのですが、スピーカはヘッドフォンに比べてインピーダンスの変化が激しい為、高域(インダクタンス成分によるインピーダンス上昇部分)での消費電力低下を補えるような値(47kΩ)を選ぶと、f0周辺の低域も一緒に持ち上がってしまって近所迷惑な音になってしまいました。このため、正帰還にHPFを仕込み、インダクタンスの影響が出る帯域だけ正帰還が効くようにすることで、インピーダンス変化が激しいスピーカ負荷でも、f0以上がなるべくフラットな出力となるようにしています。逆にf0近辺は消費電力が小さくなってしまいますが、ここから低域にかけてはそもそも急激に能率が悪くなるところですので、今回は諦めました(正帰還部にLC共振とかを仕込めばできなくはないのでしょうが…)。

このため、元回路のように「負荷に合わせて検流抵抗を設定すればOK」とはいかなくなってしまいました…。上記の回路は、対象となる負荷のインピーダンスカーブを模した等価回路を使い、LTSpiceで良さそうな出力特性になるよう追い込んで設定しています。このため、製作に際して予め使用スピーカのインピーダンスカーブを入手 or 測定しておく必要があります。

 

ちなみに、日本ビクター SX-WD5KTの等価回路は以前紹介しましたが、今回の正帰還回路を決めるにあたってPARC Audio DCU-F071Wの等価回路も作ってみましたのでこちらに掲載しておきます。例によって位相成分はアテになりません。また、メーカー公表のグラフを元にしていますので、箱に取り付けた場合は若干異なる特性になる可能性があります。

イメージ 3

これを先程のアンプに繋いだときの出力特性は以下のようになります(SX-WD5KTの方はネットワーク改造済の回路に合わせてあるので、記載を割愛します。)。
(負荷がGNDに落ちていないと正しく解析できないため、負荷側の回路が凄いことになっていますが、これでも計算すると元のインピーダンスと同じになります。)

イメージ 4

このように、正帰還によってf0以上の領域で負荷の消費電力がほぼフラットになっているのがわかるかと思います。

 

実際に使ってみた印象ですが、平衡回路化が効いたようで、ステレオ感といいますか、左右の音の分離っぷりが非常に素敵で、それによって定位も綺麗に定まっています。また、中央付近とか中途半端な定位で鳴っている音とかもグシャグシャにならず、端の方で鳴っている音と変わりなく聴こえます。差動化の恩恵がここまであるのであれば、本当はDACから入力トランスまでの経路も差動信号にしたいところですけど、うちのサウンドカードのDAC(WM8716)はアンバランス出力で、しかも中間電位の出力端子(VMIDR/L)は信号経路とは繋がっていないらしく、ここを仮想GND代わりにしても出力は得られませんでした…(いっそのこと差動電圧出力のDACチップを使ってUSB-DACでも作るか…)。

正帰還についてもそれなりに効果があるようで、マッチングのみの場合と正帰還アリでは、正帰還アリの方がアタック音(鈴とか打楽器の打撃音、或いはギターのピック弾きの音)や反響音等が綺麗に聴こえます。綺麗に録音されたものですと非常に生々しい音を出すことがあります。スタジオ録音とかだと分かりにくいですけど、ライブ録音モノ等では良さを実感しやすいです。それでいて聴き疲れも特に感じません。一方で妥協した低音域についても、特に不足は感じられません(きっとカタログスペック通り出ているんだろうなという印象です)。曲がりなりにもDCアンプですので、アンプ側の都合で低域が痩せたりする問題はないのだろうと思います。尚、DCオフセットを実測しましたが測定限界以下(約10mV未満)でした。

 

個人的には満足な結果が得られました。もし気になる方がいらっしゃいましたら、前述の制約をお守りの上、是非お試しください。