9999年12月31日金曜日

当ブログにおける注意点

全般的な注意点

Basically, all articles are written in Japanese, but please feel free to ask me to translate or explain it via Twitter, etc. At GitHub, I'm using English usually.

本ブログは個人の意見を発信する場となっています。ここで記述された情報、意見は所属する組織とは一切関係ありません。

また、記述された情報を利用する事で発生した問題についても当方では一切責任は負えません。自己責任でお願いします。

コメントの見落としが多いというか、ほとんどチェックしてなかったので、何かあればTwitter等のソーシャルメディアで突いてもらえれば捕まるかと思います。

電子工作・アーケード基板系の記事について


趣味で書いてる記事のため、わりと軽い感じで書いてたりはしますが、当方一応は電子工学学士、情報理工学修士です。元LSIの論理設計者でもあり、現役のソフトウェアエンジニアでもあります。適当にやってるようで実は難しい・あるいは危険を伴う事もあるので、専門的な知識、記事の理解なしに見よう見真似で試すのはやめて下さい。ソフトと違って不可逆な失敗のリスクはいたるところに転がっています。最悪、命を脅かすような事故にも繋がりますのでご留意下さい。不明な点はTwitter等で気軽に話しかけてもらえればアドバイスできる事もあるかもしれません。


ソフトウェア系の記事について


ソフトウェアに関しても低レイヤーの情報は一歩操作を誤るとデバイスの文鎮化、データの消失など重大な被害に繋がります。こちらも十分な知識なく、記事を鵜呑みにして実行するのはやめて下さい。


際どい技術情報について


特にメーカー保証の終了した基板の修理などは、修理・調査の過程で本来開示されていなかった技術情報、あるいは守秘義務によって守られるべき技術情報を偶発的に知ることが多々あります。調べた事は可能な限り共有しあう文化で育ってきたため、自分で調べた事は積極的に発信しています。その際、関係各所には配慮するなり、不利益がないよう考えてはいますが、所詮こちらの立場しか見えておらず、権利者からみたら不都合があるかもしれません。その際には連絡頂ければ直ちに双方にとって良い状況になるよう対処したいと考えています。よろしくお願いします。権利を持たない方からの警告等は対応いたしかねますが、個人的に妥当と思える場合には対処します。例えば権利は昔在籍した会社が所有するが、実際にその製品に関わっていた、といった人からの連絡などは間違いなく配慮します。

2025年3月9日日曜日

PC-G850とg800とApple Silicon

ポケコンPC-G850を手に入れたついでに、そのエミュレータであるg800をApple Siliconなmacでコンパイルしたので、そのメモ。

基本的にはbrew環境のSDL2を使ってコンパイルしただけで、手直しはほんのちょっとです。brewだけインストール済みって人はbrew install sdl2だけしてもらえたらって感じ。

コードで直さなきゃいけないのは以下の点だけ。基本的には古のUNIXの修正で良くやるやつで、stri*系とmemi*系をstrcase*系に直す、MAX_PATHをPATH_MAXに直す(今どきそれで良いのか?ってのは別の話)、足りてないincludeと標準関数名との衝突を避けるリネームをするだけ。

あとはmakeで警告などは出るものの、最後まで通りました。

diff --git a/basic.c b/basic.c

index 9764b01..0860a6e 100644

--- a/basic.c

+++ b/basic.c

@@ -671,7 +671,7 @@ static int encodeNumDms(uint8 *num, const uint8 *str, int dms)

        } else

                sign = 0x00;

 

-       if(strnicmp((const char *)p, "&H", 2) == 0) { /* 16<90>i<95>\<8B>L */

+       if(strncasecmp((const char *)p, "&H", 2) == 0) { /* 16<90>i<95>\<8B>L */^M

                int i;

                uint32 x = 0;

                uint8 dec[8 + 1], *q;

@@ -3213,7 +3213,7 @@ uint8 *skipBlank(const uint8 **p)

 */

 int peekSymbol(const uint8 **p, const uint8 *symbol)

 {

-       return memicmp(*p, symbol, strlen(symbol)) == 0;

+       return strncasecmp(*p, symbol, strlen(symbol)) == 0;^M

 }

 #define peekSymbol(p, symbol)  peekSymbol(p, (const uint8 *)(symbol))

 

@@ -5468,7 +5468,7 @@ static int staErase(struct Basic *bas, const uint8 **p)

 */

 static int staFiles(struct Basic *bas, const uint8 **p)

 {

-       char path[MAX_PATH] = "";

+       char path[PATH_MAX] = "";^M

        uint8 ch;

 

        if(!isTerm(p))

@@ -5614,7 +5614,7 @@ static int staGoto(struct Basic *bas, const uint8 **p)

 

 /*

 */

-static void pause(struct Basic *bas)

+static void pause800(struct Basic *bas)^M

 {

        if(*pauseWhenPrint & 0x04)

                while(getKeycode() != GKEY_RETURN)

@@ -5688,7 +5688,7 @@ static int staGprint(struct Basic *bas, const uint8 **p)

                        return ERR_10;

        }

 

-       pause(bas);

+       pause800(bas);^M

        return ERR_OK_NEXT;

 }

 

@@ -6552,7 +6552,7 @@ static int staOpen(struct Basic *bas, const uint8 **p)

 {

        int err, fileno = 1, mode = 0;

        uint8 *filename;

-       char path[MAX_PATH];

+       char path[PATH_MAX];^M

 

        if((err = fetchStr(bas, &filename, p)) < 0)

                return err;

@@ -6967,7 +6967,7 @@ static int staPrint(struct Basic *bas, const uint8 **p)

 

        if(isTerm(p)) {

                *noWrap = 0x00;

-               pause(bas);

+               pause800(bas);^M

                return ERR_OK_NEXT;

        }

 

@@ -7050,7 +7050,7 @@ static int staPrint(struct Basic *bas, const uint8 **p)

                        return ERR_10;

        }

 

-       pause(bas);

+       pause800(bas);^M

        return ERR_OK_NEXT;

 }

 

@@ -8028,7 +8028,7 @@ static int getKeywordFromName(int *code, const uint8 *name)

                        }

 

        /* RESERVED<82><A9>? */

-       if(strnicmp((const char *)name, "RESERVED", 8) != 0)

+       if(strncasecmp((const char *)name, "RESERVED", 8) != 0)^M

                return ERR_OK;

        for(p = name + 8; *p == ' '; p++)

                ;

diff --git a/iocs.c b/iocs.c

index 3cb47d1..6e1ed54 100644

--- a/iocs.c

+++ b/iocs.c

@@ -1516,13 +1516,13 @@ uint8 getChrcode(int cursor)

 

                        /* <83><8D><81>[<83>}<8E><9A><81>E<83>J<83>i<95>ϊ<B7><83>e<81>[<83>u<83><8B><82><A9><82><8D>????<EA><92>v<82><B7><82><EA><82>΃L<83><85><81>[<82>ɓ<FC><82><EA><82><E9> */

                        for(r = table; r->roman != NULL; r++)

-                               if(memicmp(roman, r->roman, strlen(roman)) == 0) {

+                               if(strncasecmp(roman, r->roman, strlen(roman)) == 0) {^M

                                        if(strlen(roman) == strlen(r->roman)) {

                                                strcpy(queue, r->kana);

 

                                                if(memory[0x7901] & 0x08) {

                                                        for(d = dai_sho; d->dai != NULL; d++)

-                                                               if(stricmp(queue, d->dai) == 0)

+                                                               if(strcasecmp(queue, d->dai) == 0)^M

                                                                        strcpy(queue, d->sho);

                                                        memory[0x7901] &= ~0x08;

                                                }

diff --git a/menu.c b/menu.c

index 9f84189..1dc1642 100644

--- a/menu.c

+++ b/menu.c

@@ -14,6 +14,7 @@

 #      include <unistd.h>

 #      include <sys/types.h>

 #      include <sys/stat.h>

+#      include <dirent.h>^M

 #endif

 #include "g800.h"


2025年2月15日土曜日

X68000 Zのキーボードまとめ

X68000 ZのEAKのキーボード、色々と曰く付きだったんだけど、Z2祭りにより気持ちが高まったので、少し調べてみたのでまとめ。

調べたキーボードは

  • Hackers Edition
  • Early Access Kit
  • Product Edition
基板に書かれたバージョンは全部同じで「V1 20220823」でした。ただ、Hackers Editionだけは2つ基板に違いがあります。
  1. X68000 Zのシルク印刷がない
  2. 制御マイコン付近のR0(153)が存在しない
R0はVCC-GND間に15kΩを刺してるようです。これ、Hackers Editionでなんらかの問題に気づいて、電源ノイズが問題だと思って入れた対策かな……

そして、Early Access KitとProduct Editionの違いは、電解コンデンサの容量。Hackers EditionとEarly Access Kitは220uF、Product Editionではこれが10uFに差し替えられてる。220はUSBにはでかすぎ。刺した瞬間にコンデンサにチャージするための突入電流が大きくて、ネゴシエーション前に許された電流上限を越えて切断されてるんでしょう。実際、自分はHackers Editionをいろんな環境で使ってきてるけど、Product Edition以外でもわりと挙動は怪しくなりがちでした。

今までコミュニティでは2つの対処方法があったようで、1つはGOROmanさんのコンデンサを10uFに交換する方法、もう1つはVbusに10Ωを直列に挿す方法。後者は電圧降下0.2V程度なので許容範囲との報告だったんですが、自分が以前計測した感じだと全てのLEDが点灯すると40mAくらいまで電流値が上がるので、その時はおそらく0.4Vくらいの電圧降下となり少し不安ありです。GOROmanさんの方は大正解なんですが、もしかしたら立場上あまりハッキリ言えなかったりするかもしれないので、変わってここで大暴露。10uFに交換するのが、Product Edition化改造としては正しい方法です。おそらく公式の修理も同じ対応かと思います。

まとめると

EditionX68000 ZシルクR0電解コンデンサ
Hackers Editionなしなし220uF
Early Access Kitありあり220uF
Product Editionありあり10uF

となります。

さて、実際の作業方法です。

まず裏面の下側の3つのゴムを剥がして、隠しネジを見つけます。この3つの隠しネジと上段の穴の中にある3つのネジ。この計6個のネジを外すことでキーボードが御開帳となります。ゴムはピンセットで引っ掛けてはずせば、そんなにダメージ与えず元に戻せる形ではずせます。中央がちょっと各ネジっぽくなってるけど、ここはシール剥がさなくて大丈夫。罠です。

ネジが外れたら開いていくのですが、爪で止められているのでスマホを開く道具とか使って開きましょう。手前側からが開けやすいです。ぶっちゃけこのキーボードに限っては爪折れても問題ないのでバシッと。ただ、無理に力加えるとカバー全体がバキッといくかもしれないので、全体が歪まないよう気をつけつつ。

蓋を外したら次はこれ。写真の通りキーキャップを外してください。下にネジがあるのがこの5つのキーキャップです。見えるネジを全て外す事で基板が下面ケースから外れます。

キーキャップ外す時は道具揃えた方が安心です。自分は過去にキャップ外そうとして貴重なレトロマシンの軸をへし折ったことが何度も……こういうやつ↓買っときましょう。ほんと便利なんで。

そして最後に電解コンデンサの交換。

中央付近に電解コンデンサ、そのすぐ下にC5、R0と見えるかと思います。コンデンサはたぶんスルーホールじゃないと思うので、片足ずつハンダ小手で温めて引っ張れば簡単に外れます。それかペンチでバッサリ切り落とすのも全然あり。(2/15訂正:綺麗にハンダを剥がして確認した方の情報によるとスルーホールのようです。外しにくい時は足が抜けるよう上方に垂直に引っ張ってみて下さい。)

という感じで、作業としてはわりと簡単だけど、キーボード分解する時にケース傷つけたりとか、それなりの事は起きうるので、自分で作業する場合は自己責任で。慣れてない人は条件(前回のクラファンでEAK、今回のクラファンでZ2購入)を満たしてれば無償で直してくれるみたいなので、無理せず頼んじゃった方が良いと思います。一日たりとも手放せない or 魔改造大好きって人はこの方法でやっとけば、とりあえず電気的にはオマ環にはなりにくいのでないかと。

2024年12月28日土曜日

mac mini 2024とintel資産運用

前ふり

mac miniのARM移行については、DAW系ソフトとかも含め心配事が多いので踏ん切りがつかなかったのですが、mac mini 2024の超小型化に心動かされ、頑張って移行する事にしました。

一般ソフトの移行

最近のやつなら、ほぼUniversalでパッケージされていて、ARMで起動すればARM版が動いてくれます。万が一古いIntelバイナリだったとしても、Rosetta 2経由で快適に動きます。例えばVLCのビデオエンコードとかはIntelバイナリを変換して動かした方が速いくらいだし、Unreal Engineみたいな重たい開発環境でも、新しい版ならUniversal、古い版ならIntel版が快適に動いてます。

少し気にしないと行けないのがPlug-in系。例えば配信ソフトのOBSはVLCがインストールされてるとVLCを入力ソースとして選び、映像ストリーミングを受信したりできますが、お互いインストールされてるバイナリタイプが一致していないと拡張として認識されません。例えばOBSだけ最新版でUniversal、VLCはIntelって場合は、ARMに移行した時にOBSだけARMで動くようになり、VLCの拡張が利用できなくなります。このような場合、VLCをUniversalかARMに更新すれば連携できるようになります。もし両者をARMで揃えられない場合は、UniversalアプリをRosetta経由で強制的にIntelバイナリで起動するという方法もあります。

DAWやVST/AUの対応事情

DAWやDJソフトなんかはわりと早期にARM対応してたみたいで、今なら特に困ることなく移行できます。が、VST/AU周りは少しハマりポイントも。

VST/AUは基本的には先述のPlug-in問題と同じで、基本的にはアーキテクチャが一致してる事が望まれます。が、調べた範囲だとAUに関してはOSレベルでクロスアーキテクチャをサポートしてるので透過的に使えるらしく、全てのDAWでサポートされてると思って良さそう。VSTに関してもDAWごとに内部的にブリッジ用意して使えるように努力してくれてます。

FL Studio ... この辺で説明されてるけど、ARM版で起動してもIntel VSTをブリッジしてくれます。Intel AUは少しはまりポイントがあったので後述。

Cubase ... VST3はARM版しかサポートせず。VST2に関してはIntel版もブリッジしてくれます。古くて移行してくれてないやつはだいたいVST2なので納得感ある、かつ公式らしい対応。

Studio One ... 2でも3でもIntel VSTをブリッジしてくれる。

AUに関しては落とし穴があって、読み込み時にシステムダイアログで警告を受けます。

ここでうっかりゴミ箱に入れないようにしましょう。「このまま開く」から許可する手順に入ります。すでに具体的な事はわすれてしまったけど、もしかしたら左のダイアログが先に出て、人まずは完了でパスして、この後にシステム設定に設定項目が現れて、そこから許可をすると右のダイアログで許可できるようになったかも。システム拡張とかパーミッションの設定と近いプロセス。

で、落とし穴は、このダイアログがでない環境があるって事。自分のケースではFL StudioではSynth1は黙殺されてましたが、Studio Oneでこのダイアログが表示され、そこから承認プロセスを通したらFL Studioでも使えるようになりました。

あと、マシン移行時にライセンスの再認証が必要なPlug-insが多いと思うので注意しましょう。自分の場合、iZotopeの再認証をしてなかったため、Studio Oneで定期的に音切れが発生する、という現象に悩まされてました。

新規仮想マシンの運用

もし一般的なWindowsアプリが動かしたい場合は、Parallelsか無償になったVMware Fusion経由でARM版Windowsを動かすのがおすすめ。ARM版Windows自体がIntelバイナリを実行する機能を持っているため、大半のソフトは問題なく動きます。問題が起きるとすれば、特殊なドライバを必要とする開発系ツールなど。あとはゲームでアンチチートに弾かれる事はあります。最近の需要で言えばVRChatが該当します。かつては問題なく動いていましたがEAC導入後は弾かれてます。VCRChatに関しては公式から非公式情報が出ており、エミュレーションするハードウェアの固有値をうまく設定する事で回避できるようですが、ARM版Windowsのバイナリ変換ではこの辺の固有値は設定できないので対応不可と思われます。

Linuxに関しても、今はARM版LinuxからRosetta 2経由でIntel版アプリを動かす事もできるようになってます。という事で、いずれの場合の新規OSインストールが許容できるなら、ARMベースで動かしてアプリレベルで必要に応じてIntelバイナリを変換、というのがパフォーマンス的にもベスト。

Intel仮想マシンの移行

すでに運用してたIntel版Windowsをそのまま持ち越したい、という需要が大きいとは思うんですが、ビジネスでそれをサポートしてくれてるとこは残念ながらありません。今のところ、そこそこうまく言っているのは、UTMでqemuのバックエンドを使い、Intelシステムエミュレーションの上で変換したVMイメージを使う方法くらいです。以下、注意点をいくつか。

事前にParallels関係のVM補助ツールは全部アンインストールしましょう。残っていると他のVMに持っていった際に関連ドライバ(prl_strg.sys)が起動中にクラッシュします。

Parallelsのディスクイメージは、snapshotとったりサイズ可変の設定になってたりすると変換がうまくいきません(サイレントに壊れて、起動失敗したところで深く悩みます)。元のマシンでこれらの設定をはずしてから、 /Applications/Parallels Desktop.app/Contents/MacOSts/MacOS/prl_convert などを使ってplainなフォーマットに変更しましょう。そこまで変換しておけば、UTMでファイルを選択した際にqcow2形式に自動変換した上でVMのフォルダ内にコピーを作ってくれます。

UTMに持ってきたら、CPUのマルチコア設定に注意。qemuはマルチコアエミュレーションをする際、コアごとに別スレッドでエミュレーションをするので物理スレッド数くらいまでエミュレーションするCPUを増やせばスケールするはず!と思うと失敗します。ARM上でIntelをエミュレーションするのは、strong-on-weakと呼ばれるケースに該当します。要はマルチコアにおけるメモリ一貫性保証の制約がARMの方がパフォーマンスを出しやすいweak memory orderを採用している。その上でより制約の厳しいstrong memory orderをエミュレーションするのは難しい/オーバーヘッドがでかいです。そのため、デフォルトでは正確性を優先してマルチスレッド対応は切られてる。そこで、システム設定にある「マルチコアを強制」にチェックを入れると、memory consistencyのサポートは諦めてマルチスレッドで動くようになります。この設定を受け入れないと実用的な速度では動きません。qemuの方でも一応バランスを見てバリアを埋めてくれてはいるようで、実用上は問題にはならない気はします。実際、ARM版Windowsのバイナリ変換でも標準設定でははmemory consistencyは壊れてます。実行ファイルのプロパティにある互換性設定でバイナリごとにエミュレーション精度を指定できるようになっており「標準設定でうまく動かなかったら、ここを変えてね」という扱い。一方Rosetta 2に関してはApple Silicon側にstrong memory orderをサポートする仕掛けがあり、正確かつ高速なエミュレーションができている、と言われてます。ほんと夢がある石なんだよ……。

Windows 10のイメージを持ってくるのに使ってる設定は以下の通り(いじったとこだけ)。

アーキテクチャ: x86_64
システム: Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-9.1) (q35), 8192MiB
CPU: デフォルト, 4コア, マルチコアを強制
QEMU: 「ベースクロックにローカル時間を使用」のみチェック(非UEFI環境)
ディスプレイ: virtio-vga-gl (GPU Supported)

Linux系を持ってくる場合もParallels用のドライバは削除した方が良いみたい。GPU Supportedなディスプレイカード設定を入れると画面が落ちるのは古いせいかと思ってたら、どうもParallels用のドライバが悪かった。/Applications/Parallels\ Desktop.app/Contents/Resources/Tools/prl-tools-lin.isoあたりをマウントしてinstallerを実行すれば、uninstallが選べます。これでUbuntu22でvirtio-gpu-gl-pci (GPU Supported)が動くようになった。それまではvmware-svgaしか動いてなかった。virtio-ramfb-gl (GPU Supported)がいけるという話もあるけど、自分は動かなかった(けど、Parallelsの掃除してからは試してない)。

既存のVMイメージの流用だけじゃなく、どうしてもIntel版Windowsが必要って場合もUTMで同様の設定で新規インストールするのが唯一の解だと思います。新規の場合はギャラリーにあるイメージが最適設定の参考になるかと。VRChatのハードウェア設定もUTMで設定いれればワンチャン動くかもしれません(未確認)。

Wine

そうそう、Wineryとかwine系ラッパーで作ってあったパッケージはそのまま快適に動いてます。たぶんRosetta 2経由で起動してる。

その他

何から何まで移行・動作確認できてるわけじゃないので、他にも色々とあるかも。

例えばbrewとかはARMだとインストールする場所が変わるので、intel版残したままARM版も入れて様子見てる。

VS Codeの拡張とかもintel依存多いので怪しい。たぶんログアウトして同期を切ってからアプリとデータを削除、再インストールするのが正しい……けど、やってない。同期したままファイル消したりすると伝播するので危険……というのは以前経験した。

VRChat動かしたい人は、ARM版LinuxでRosetta for Linuxを使ってSteamを動かせば、Proton経由で動く可能性がありますね。少なくともSteamDeckではProtonでEAC突破できてるので。

追記(2024/12/31):Rosetta for Linuxはx86_64しかサポートしてない模様。Steam Launcherが32bitアプリなので一工夫必要。i386だけbinfmtにqemuを登録するとか?と思って試してみたけど、最終的にはlibGLの中で落ちた。

試したい人向けにやった事のメモをしとくと、UTMでGalleryにあるDebian 12 (Rosetta)をインストール、その中で以下の作業を敢行。

sudo apt install qemu-user-static
sudo update-binfmts --install qemu-i386 /usr/bin/qemu-i386-static --magic '\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
sudo dpkg --add-architecture i386
sudo apt update
# https://store.steampowered.com/about/ から steam_latest.deb をダウンロード
sudo apt install ~/Download/steam_latest.deb
steam

Xに垂れ流してた作業ログを簡単にまとめただけなので、もし詳細を教えて欲しい!ってとこがあれば、Xで声かけてください。分かる範囲でなら答えたり追記したりします。