honeylab's blog

各種ハードウェアの改造、主にファミコンミニなどをやってます(ました)

NEOGEO Arcade Stick ProのOSSソースコードが公開されました!

過去2回分の以下の記事でさんざん悪態をついたOSS非公開の件、
どうやら2回目の記事を書いたちょっとあとぐらいにリンクが変更され

https://github.com/xudarren/NeogeoASP_OSS

こちらのサイトでソースコードが公開されたようです。

記事で指摘した".s"がツリーに戻されていた件も是正され
正しいソースコードに修正されたようにも見えます。
LGPLであるQUIのソースもオブジェクトコードが公開されました。
まだ詳細未確認ですが、この件については一定の対応があったと考え
煽るような内容でソースの公開を迫った態度を若干反省し
ソースコード公開に関わった関係者の皆様に感謝します。

(※GPL宣言のあるソースが本当に著作権者のものであるかどうかって言う点の確認が足りなかったところなど、今後に活かしたいと思います。)

 

honeylab.hatenablog.jp

honeylab.hatenablog.jp

Add Starisotope204515i47_rozray
  • jin

    BOOTHで少し前にやり取りした者なんですが、いろいろ思うところがありましたのでここでコメントします。

    まずBOOTHにおける説明で「事業者の名称・連絡先」について

    「省略した記載については、電子メール等の請求により遅滞なく開示いたします」

    と書いてあったのに、いきなり

    「記述間違いで、販売業者に該当いたしませんので名称・連絡先について開示いたしません」

    と修正されましたが、詫びもせずにそのようなことを行う態度こそ散々自身でSNK社を非難したような「姑息」な姿勢というものじゃないんでしょうかね。
    だったらあなたも「他人の事言えた義理じゃない」と率直に思いますし「何をエラそうに」と現状思わざるを得ません(個人的見解)。

    ついでに単に「販売業者に該当いたしません」となんの根拠もなしに言われても信じようがないんですが、それこそ「ソースコードの公開」にでも倣って「販売業者に該当しない具体的根拠」を示すべきなんじゃないでしょうか?
    それについてはいろいろなものがあると思いますが、「デタラメな対応」を自分はしない、というのであれば是非とも「具体的根拠」をお示しの上ご証明下さい。
    (別にネット上に公開する必要はなく、私個人宛で結構ですし、確認以外他意はありません)

    さらに
    http://honeylab.hatenablog.jp/entry/2019/12/02/153056

    >それでも日本のお国柄、あんまり派手にとっちらかすとメーカー以外のところからあれやこれや言われて嫌な気分になるのでほどほどにしておきますが…)

    これは「日本のお国柄」があなたを「嫌な気分」にさせるハラスメント体質だとでも言いたいんでしょうか?
    実は私はこの文面があったので「それに倣っても」記載する必要があったんじゃないかと思うんですが、上記のような意味なんでしょうか?
    別にあなたが嫌な気分になろうがなるまいが勝手でありなんの気にもしませんが、「日本のお国柄」を自分勝手に貶めるようなことを言われるのはこっちこそ「嫌な気分」になりますよ。
    まさに「何様のつもりだ」と反吐が出るといってもいいぐらいですよ。

    あなたがどこの高邁な「何国人様」か知りませんが、この国には「言論の自由」というものがありますので存分に反論させていただきます。

    何卒宜しくお願い致します。

コメントを書く

SNKによるNEOGEO Arcade Stick ProのGPL逃れ(解消されました!)の手口と彼らのミス

以下、https://github.com/xudarren/NeogeoASP_OSS の公開によりいったん打消し線扱いにします

 

 

honeylab.hatenablog.jp

 

前回の記事

honeylab.hatenablog.jp

の続編です。

相変わらずSNKは内蔵Linuxカーネルソースコードを公開していませんが、
前回ひっそりと公開された内蔵エミュレータソースコードと主張するものを分析してみたいと思います。

 

文章がクソ長くなってしまったので結論だけ先に書いておきます

 

公開された「エミュレータソースコード」は、
ASPで使用されているエミュレータソースコードではない」ということです。

これは、明確にGPLの要求する事項を満たしてはいません。

 

以下、その結論に至るまでの経緯です。

 

 

エミュレータ"mvsnjemu"のソースコードとして公開されたリポジトリはこちらです。

https://github.com/xugamezhouyuhua/neogeoaspemu

移植元の"NJEMU"のリポジトリの一つはこちらです。

https://github.com/phoe-nix/NJEMU

パッと見てみると、NJEMUの機能のうち、CPSなどの部分を取り除き、
名前の通りMVSのエミュレータとして機能を抽出したように見えますが…

 

まず、バイナリをビルドするためのMakefileを見てみます。

https://github.com/xugamezhouyuhua/neogeoaspemu/blob/master/Makefile

main関数のあるemumain.cや外部ライブラリ zlibなどのソースファイルは
拡張子".c"であるC言語のソースファイルを参照するようになっています。

しかし、エミュレータのコアに近い"mvs"フォルダや、
機種依存部分を記述したと思われる"elinux"フォルダの中にあるファイルは、
アセンブリ言語である".s"の拡張子を持ったファイルを使用するように記述されています。

https://github.com/xugamezhouyuhua/neogeoaspemu/blob/df0b7990066001b6a21b9270766d5cae5e60719d/Makefile#L47

ところが、この"mvs"フォルダには、移植・変更前と寸分違わぬ".c"ファイルも納められたままです。

f:id:honeylab:20191205145744p:plain

"biosmenu"の".s"ファイル

https://github.com/xugamezhouyuhua/neogeoaspemu/blob/master/src/mvs/biosmenu.s

"biosmenu"の".c"ファイル

https://github.com/xugamezhouyuhua/neogeoaspemu/blob/master/src/mvs/biosmenu.c

 

それなのに、Makefileからは参照が外されています。
通常、いわゆる「コンパイル」作業をすると".c"からアセンブリ言語".s"ファイル、objファイルなどを経由し、実行ファイルを生成します。
そのため、こういったソースツリーには中間生成物である".s"を含めないのが普通です。

上のリンクの.c と.sを見てみるとわかるように、C言語は通常人間が書くもので、いわゆるプログラミング言語の体を成しています。
しかし、コンパイラによって生成された.sファイルは簡単に読めるものではありません。(画像:アセンブリC言語の対比)

f:id:honeylab:20191205145246p:plain

 

それを逆手に取り、SNK(外注先)は、変更点を分かりにくくするため、元のC言語ファイルを手元に置き、修正したC言語ファイルをコンパイルしてできた

中間生成物の".s"ファイルのみをソースファイルと言い張ってソースツリーの中に戻したのです。


.sファイルは一から手で書くこともできますが、ここでツリーに挿入された.sファイルには、gccコンパイラ)によって生成されたものですよ、という注釈が取り除かれないまま残されています。

https://github.com/xugamezhouyuhua/neogeoaspemu/blob/df0b7990066001b6a21b9270766d5cae5e60719d/src/mvs/biosmenu.s#L460

f:id:honeylab:20191205145436p:plain

 

参照された"NJEMU"はPSP用として作られたようで、PSP用のSDKにしか存在しない関数を多数使用しています。しかし、その記述は.cの中にしか残っていません。
そのような機種依存部分と、自社の製品に合わせた変更を行った.cファイル(例えば"bios.c"ではエミュレータの使用中にBIOSファイル」を選択する機能無効化する変更が行われています。)は彼らの手の中にしかありません。

GPLを定義しているFSFのとしては、そのような行為は難読化と同等で、
ソース公開したとはみなさない、という主張もあります。
また、どうやら"NJEMU"では正常に動かなかったROMに対して、
自分たちの機械では動くように修正した部分などもあるようです。

f:id:honeylab:20191205150233p:plain

(画像:"Sengoku3"のROMを読み込んだ時に何らかのパッチを当てている部分)

 

もともと、彼らの(先祖の)機械をエミュレートした、という立場ではありますが、
主要部分をほとんど丸々コピーして使いつつ、都合の良いように改変して
それを秘密にし、還元しない、というのはOSSの考え方に対して
真っ向から砂をかけているようなものだと感じます。

さて、ここまでは難読化逆アセンブルソースをツリーに戻したという
精神的な反OSS行為に対する暴露でしたが、彼らは一つ(以上)ミスを残していました。

 

メイン関数があるemumain.c 、これに関してはソースコードや".s"ファイルをツリーに戻していません。mvsnjemuのemumain.cは以下のファイルですが、
https://github.com/xugamezhouyuhua/neogeoaspemu/blob/master/src/emumain.c

Arcade Stick Pro(ASP)にインストールされたmvsnjemuの実行ファイルを解析したところ、明らかに上記のコードとは違う動作をしていました。

main関数では、起動時のディレクトリをgetcwd関数で取得し、その文字列を加工してROMやキャッシュファイルの場所を決定するようになっていました。
しかし、ASPでは実行ファイルとROMのファイルの場所が大きく離れています。そのため、この部分を手っ取り早く固定文字列に変更する、という変更を加えていました。

以下のリンク先のソースコードは、"Ghidra"というツールを使用して、main関数を逆アセンブルしたものに注釈を書き加えたものです。

https://bitbucket.org/snippets/bakueikozo/8nMMAB

固定文字列をリソースとして使用してしまっているため、出力された実行ファイル内にもこの文字列は残ってしまっています。(下画像)

Image


このemumain.cをコンパイルして出力された.sファイルはなぜかツリーに戻されず、emumain.cにも変更が反映されていません。
もちろん、公開したとするリポジトリ内に"/mnt/"のような文字列は含まれていません。これは、ASP上で動かすためだけに必要な情報だからです。

 

つまり、公開された「エミュレータソースコード」は、
ASPで使用されているエミュレータソースコードではない」ということです。

これは、明確にGPLの要求する事項を満たしてはいません。


もはやSNKのサポートにメールを送ったところで個別に対応されるとは全く思っていませんが、彼らには、OSSの利用に対するルールとして、著作権情報の表示と必要なソースコードの提供を行ってくれることを切に希望します。

ところで、たまに私のことをGPL警察みたいに呼んでくれる人がいるみたいですが、
私はGPL警察でも何でもありません。大した権利者でもないし。


ただ、私はこのGPLの成果物が入った機械に払った金銭には、
このソースコードの分の価値が入っているはず、と信じて購入しているのです。
その分がついてこなかったので、ブーブー文句を言っているだけなのです。


この部分をきちんとしているゲームコンソール等のメーカーは、それをきちんと原価だと考えて対応しているはずです。
それを入れないまんま、うっぱらっておしまいなのは、
ちゃんとそれを原価に入れてるメーカーにケンカを売ってるんだと思うんですよね。

 

以上、ソースツリーの検証と手口の解析 おしまい。

 

(解消されました!)GPL違反状態になっていたNEOGEO Arcade Stick Proの解析情報

先ほど確認したところ、OSSソースコードリポジトリが公開されたようです。

以下、一旦打消し線扱いにします。

 

https://github.com/xudarren/NeogeoASP_OSS

 

honeylab.hatenablog.jp

 

先日発売され、分解していろいろ遊んでいる NEOGEO Arcade Stick Proですが、

(以前の記事を読んでいない方はこちらを先にお読みいただくとより詳しいです)

honeylab.hatenablog.jp

honeylab.hatenablog.jp


解析しているうちに、以下のソフトで構成されていることがわかっています。

・OS Linux 3.4.0+ (Android kernel for Actions semiconductor Soc ATM7029)

エミュレータ "mvsnjemu"

・ソフトウェア

 ・SNK_MAIN (ELF executable) (QUI_G1のローダ&アップデータ実行環境)

 ・QUI_G1 (ELF executable) (黄色いゲームメニューUI)

 ・そのほか 若干のシェルスクリプト

 

このうち、Linux 3.4.0は GPL v2のはずで、私の言葉でいうと「このソフトウェアのバイナリを受け取った者に対し、ソースコードの請求に応じる必要がある」ということになっています。これに応じない場合、いわゆるGPL違反」状態になります。

また、これらGPLのソフトウェアを使用していることおよび、その著作権表示を行わなければいけないことになっています。

 
(以下のリンクを参考にしています)

https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.ja.html#CompanyGPLCostsMoney

 

例えば、同様にLinuxを採用しているニンテンドークラシック ファミコンミニ などではこちらのサイトで紹介されているように、

www.banwanko.net

ゲーム内の「権利表記」から確認することができるようになっています。
使用しているライブラリのひとつひとつについて名前と著作権表示が行われているはずです。
また、任天堂の公式サイトで必要なソースコードの公開が行われています。

www.nintendo.co.jp

(公開、としていますが、必要なのは請求者に届けることです。公開のほうが簡単な場合、このような手段になることが多いです。)

 

NEOGEO Arcade Stick Proでは、少なくともLinuxに関してこのようなソースコードの公開(もしくは、使用したオリジナルのソースコードを入手できる場所の案内)及び、このような権利表記を行っていません。
それっぽい 以下のような表示は行われていますが、これはGPLのソフトウェアを使用している、ということだけを示していて、何の権利表記を満たしたものでもありません。

f:id:honeylab:20191202155513j:plain



よりによってGPLであることを明示しながら義務を果たしていません。
ぬけぬけと「使用許諾されている」と書いてありますが、
許諾すらされていないことになりかねません。

表の人だけではなく中の人がGPLに関して全く理解していない可能性さえあります。

 

加えて、エミュレータである "mvsnjemu"は、話によればGPLであるnjemuというエミュレータからのforkであるとの噂。別の製品であるNEOGEO miniでも使われているものとほぼ同様のようですが、機種依存周りは変更されているはずです。

このようなGPL問題はNEOGEO miniでも存在していたはずですが、Linuxソースコードは最終的に公開されていません。
また、エミュレータソースコードとされるものがしぶしぶ公開されましたが、
一部がcソースから生成されたobjの逆アセンブルであるなど、
なかなか悪質な状態のようでした。

(私はNEOGEO miniを所有していないので、請求する権利はありません。)

 

先日、上記の件を簡潔にまとめてSNKのサポートに連絡したところ、ホームページで公開する準備を始めた、とのことでまったり見ていました。

(以下送信した文面)

f:id:honeylab:20191202143657p:plain

これが11月15日のことです。

それから2週間ほど経った12月1日、ホームページを確認すると、

ページ下部に「オープンソースソフトウェア」の表示がありました。

f:id:honeylab:20191202143446p:plain

これをクリックしてみると

https://github.com/xugamezhouyuhua/neogeoaspemu

というそっけないgitリポジトリのページが開きました。
NEOGEO Miniの時と同じ対応のようです。

ほかのゲームコンソールのように、権利表記を行うこともなく、
中途半端にエミュレータソースコードを(しかも一部を逆アセンブラの出力に置き換えるという姑息な手段で)公開したところで、お茶を濁そうというのでしょうか。

SNKのサイトを見ると「ライセンス事業」ということで、自社保有のIPを提供した
各種事業を行っているようですが、
他人のIPは踏みにじっていくスタンスのようです。

https://www.snk-corp.co.jp/license/

 

ということで、本体を入手して割とすぐに解析していろんなことがわかってはいたものの、SNKにはSNKなりのゲームアンロックとか周辺機器発売とかのちょっとしたプランがあるんだろうと侍的に黙っていたのですが、わりとどうでもよくなりました。

 

だから全然売れてないんだよ。Twitterで検索しても全然情報がないんだけどwww

 

というわけで、追加の解析情報をぼちぼちとまとめていきたいと思います。

私が普段こういった機器を解析するときは、まず実行バイナリをstringsに書けるあたりからやっていくのですが、今回は趣向を変えて上に書いた"QUI_G1"をRetDecというオープンソースの逆コンパイラにかけてみることにしました。

forest.watch.impress.co.jp

このソフト、なかなかのメモリ喰いで、普段作業している人権のない4GBメモリのマシンでは途中終了してしまっていました。
仕方なく、メモリをかき集めて64GBのマシンを作ったところ、ようやく逆コンパイルができ、結構有用な情報を得ることができました。
(※逆コンパイルの権利について後に書きます)

コンパイルとは言いますが、こういった実行ファイルでは関数名などの情報が失われていることが普通です。そのため、関数名は単なるアドレス名に置き換えられます。

f:id:honeylab:20191202145440p:plain

この関数の中身を見てみると

// Address range: 0x194f6c - 0x194fa8
int32_t function_194f6c(int32_t a1, int32_t a2, int32_t a3, int32_t a4) {
    // 0x194f6c
    g_r3 = a4;
    g_r2 = a3;
    g_r1 = a2;
    g_r0 = a1;
    int32_t v1 = g_r3; // 0x194f6c
    int32_t v2 = g_r5; // 0x194f6c
    int32_t v3 = g_r1; // 0x194f70
    g_r3 = v3;
    g_r4 = v3;
    uint32_t v4 = *(int32_t *)(v3 - 4); // 0x194f78
    g_r2 = v4;
    int32_t v5 = g_r0; // 0x194f7c
    g_r5 = v5;
    int32_t v6; // 0x194f98
    int32_t v7; // 0x194f90
    if (v4 >= 0) {
        // 0x194f88
        g_r0 = v3;
        g_r0 = function_194e04(v3);
        v7 = g_r1;
        g_r3 = v7;
        v6 = g_r5;
    } else {
        v6 = v5;
        v7 = v3;
    }
    int32_t v8 = *(int32_t *)(v7 - 12); // 0x194f94
    g_r1 = v8;
    g_r0 = v6;
    *(int32_t *)v6 = v8 + v7;
    g_r3 = v1;
    g_r5 = v2;
    return g_r0;
}

 

 こんな感じで、果たして何をしているのかわからないことがほとんどです。
しかし、ちょっとした手掛かりをもとに少しずつ関数を解析していきます。

今回、"QUI_G1"と"SNK_MAIN"はSDLを使用していそうだ、ということがざっくりとした解析からわかっていました。
そのため、"SDL"という文字列を検索してみます。

すると、例えば以下のような部分が見つかります。


// Address range: 0xe609c - 0xe6114
int32_t function_e609c(void) {
    int32_t v1 = g_r4; // bp-8
    int32_t v2 = &v1; // 0xe60a0
    g_r1 = (int32_t)"/dev/fb0";
    g_r2 = (int32_t)"/dev/fb/0";
    g_r3 = 0;
    g_r0 = (int32_t)"SDL_FBDEV";
    int32_t v3 = func_getenv("SDL_FBDEV", (int32_t)"/dev/fb0", (int32_t)"/dev/fb/0", 0); // 0xe60b4
    g_r0 = v3;
    g_r1 = v2;
    int32_t v4 = v3 == 0 ? 4 : 0;
    g_r3 = v4;
    int32_t v5 = v4 + v2; // 0xe60c8
    g_r2 = v5;
    int32_t v6 = *(int32_t *)(v5 - 16); // 0xe60d0
    g_r0 = v6;
    if (v6 == 0) {
        // 0xe610c
        return 0;
    }
    // 0xe60dc
    g_r4 = g_sp + v4;
    g_r1 = 2;
    g_r2 = 0;
    int32_t v7 = func_SYS_open(v6, 2, 0, v4); // 0xe60f8204
    g_r0 = v7;
    int32_t v8; // 0xe60f8
    if (v7 >= 0) {
        v8 = v7;
      lab_0xe6104:
        // 0xe6104
        function_160d30(v8, 2);
        g_r0 = 1;
        // 0xe610c
        return 1;

※(func_getenvとfunc_SYS_openは私がほかの部分を解析して置換したものです)

"SDL_FBDEV"という文字列リソースなどが見つかります。
このような文字列の手がかりや、システムコール呼び出しなどを手掛かりに、関数名を少しずつ置換していきます。

        g_r7 = 5;
        __asm_svc(0); // SYS_open     

このようなコードがあった場合、システムコール5番のopenが呼ばれている、ということです。これが含まれる関数は、ファイルなどを開いている可能性が高いです。

 

最終的に、"QUI_G1"には、zlibやlibpngなどもあわせてリンクされていることがわかりました。zlib,libpngのライセンスは"zlib"ライセンスですので

https://ja.wikipedia.org/wiki/Zlib_License

著作権表示の義務はありません(結構表示している機器はありますが)

しかし、SDLはどうでしょう。

https://ja.wikipedia.org/wiki/SDL

ファミコンミニやプレステクラシックなどではSDL2というSDLの後継ライブラリが使用されていました。
SDLのバージョン2はzlibライセンスであり、ソースコードの公開や著作権表示の義務はありません。
しかし、SDL(バージョン1)についてはLGPLというライセンスになり、一定の義務のもとライセンスされることになっています。

https://ja.wikipedia.org/wiki/GNU_Lesser_General_Public_License

簡潔にまとめると

・動的リンクなら何もする必要なし

・静的リンクなら、オブジェクトコード等、ライブラリの別のバージョンとリンクするための仕組みを提供する必要がある

著作権者情報の表示

などの義務があります。

私にとっては、ここまでデタラメなことをしたメーカーが嫌な思いをした方が面白いため、この実行ファイルがSDLバージョン1を使用している、という可能性について調査しました。すると、同様のSDL関連の部分で"SDL_CDROM"などの環境変数を参照していることがわかりました。SDLの1→2の移行の際に、ネイティブCD-ROMのサポートの打ち切りがあることは既知のことでした。

例えば

    function_10502c("Invalid starting track", v8, a3, v16);

に含まれるこの"Invalid ending frame for track"という文字列は、SDL_cdrom.cに含まれますが、このファイルはSDL1にしか存在しません。

f:id:honeylab:20191202153000p:plain

その他、上記の文字列も明らかにSDL_cdrom.cに含まれるものです。

参考: https://github.com/turican0/dosbox-x-remc2/blob/master/vs2015/sdl/src/cdrom/SDL_cdrom.c

かりにSDL2とSDL1が混在していたとしても、このファイル内に明確にLGPLの宣言があります。

そのほか、類似の手がかりを探していきました。

そのような断片をつなぎ合わせ、さらに添付されたエミュレータ"mvsnjemu"は明確にSDLバージョン1を使用していて、改めて別のライブラリを開発環境に入れるだろうか、ということなどからも、この二つの実行ファイルはやはりSDLバージョン1を使用していて、静的リンクされている、という強い確信を持っています。

その場合、『LGPLv2.1第6節またはLGPLv3第4項の条項により、「顧客(カスタマー)自身の利用のための改変ならびにそのような改変をデバッグするためのリバースエンジニアリング」を許諾する必要がある』という規約から、このようなリバースエンジニアリングはライセンス上禁止することができない(Wikipediaより)、という状態にあるということです。

一部のゲーム機などでは、ソフトウェアEULAなどでリバースエンジニアリングの禁止を条件にしたりすることがあり、そのような場合(仮に実際には行っていたとしても)このようなメーカーが権利を持っていそうな部分を解析した結果を公開することはあまりしていませんでした。しかし、あまりにもSNKがデタラメなので、こちらはこちらでリバースエンジニアリングして遊んでいきたいと思います。

 

(※配布元がLGPLを謳っていないのに、こっちがそうだといって通るかどうかとかいうことは私にはわかりません。しかし、契約で明確に禁止されていないものをやったところで、ということもありはしますが、それでも日本のお国柄、あんまり派手にとっちらかすとメーカー以外のところからあれやこれや言われて嫌な気分になるのでほどほどにしておきますが…)

 

ということで、SNKのあまりにもデタラメな対応のせいで
GPL違反状態になっているNEOGEO Arcade Stick Proの解析情報パート1でした
(長い…)

 

(ライセンス周りについて、間違いや勘違いがある可能性がありますので、見つけた方は是非指摘してください)

 

続きを書きました

honeylab.hatenablog.jp

NEOGEO Arcade Stick Proシステム詳細

前の記事で、シリアルが出力されない、と記述しましたが、

honeylab.hatenablog.jp


ハック対策なのか部品点数削減なのかはわかりませんが
一部の部品が実装されていないだけでした。

f:id:honeylab:20191113141114j:plain

基板裏面、シールドを外してR44がSoCのTXと4ピンのTXピンの間に直列に挿入される回路になっていますが、これが実装されていませんでした。
この部分に適当な抵抗をはんだ付けするか、保護を気にしなければジャンパするだけでTX出力が有効化されました。

R38がRXに直列接続かと思ったのですが、こちらは片側がVCCに接続される(プルアップ)だけだったので、ここは空のままでOKです。電圧レベルは3.3V系(TXは3Vスイングでした)です。

 

この方法で起動ログが取得できました。全体は以下のリンクにあります。

https://bitbucket.org/snippets/hiromitu/GrgMz6

ところで、この起動ログの後、ログインプロンプトが…と思ったら

普通にシェルのコンソールでした…

f:id:honeylab:20191114102440p:plain

ぇぇぇぇぇ…

さて、使用しているLinuxのバージョンは…?

root@snk:/ # uname -a
/system/bin/sh: uname: not found

あれ、unameコマンドが無いぞ…?
すごいシュリンクしたrootfsなのかな…?

127|root@snk:/ # cat /proc/version
Linux version 3.4.0+ (frank@ubuntu) (gcc version 4.6.3 (Sourcery CodeBench Lite 2012.03-57) ) #57 SMP PREEMPT Sat Oct 12 02:02:05 PDT 2019

/proc/versionから見えました。

ちゃんと、Linuxですね。
ところで、Linuxを使用しているからにはGPLに基づいた権利表記とソースコードの公開が必要なはずですが、

権利表記が適当…っていうか、これよく見たら使ってるよ、しか言ってないな…

ソースコードも今のところ公開されておらず…

取り合えず、サポートにソースコード頂戴ね、ってメールしておきました。

もしかすると、今後のシステムアップデートで更新されるかもね!!!

さて、なんでunameすらないのかな…といろいろ調べてみると、どうやらKernelの起動後、Androidシステム(という言い方が正しいのかがわからない)が起動されているようです。

Processor : ARMv7 Processor rev 1 (v7l)
processor : 0
BogoMIPS : 1022.18

processor : 3
BogoMIPS : 1022.18

Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0

Hardware : gs702c
Revision : 0000
Serial : b6db2d7d18a7c7a7

cpuinfoはこんな感じ。普通にARMでした。

NEOGEO miniのATM7013HがMIPSだったので、こいつもMIPSなのでは…と思っていたのですが、さすがにそうではなかったようです。
ARMであれば、追加で何かのプログラム・エミュレータを入れたりするのも簡単です。

Android Kernelで動いてはいますが、メニューやエミュレータは普通のELF executableでした。
なんでわざわざAndroid…と思ったのですが、

/system/build.propを覗いてみたところ

root@snk:/system # cat build.prop
ro.build.id=KOT49H
ro.build.display.id=Demo_7051H-user 4.4.2 KOT49H eng.songzhining.20161121.190628 test-keys
ro.build.version.incremental=eng.songzhining.20161121.190628
ro.build.version.sdk=19
ro.build.version.codename=REL
ro.build.version.release=4.4.2
ro.build.date=Mon Nov 21 19:10:55 CST 2016
ro.build.date.utc=1479726655
ro.build.type=user
ro.build.user=songzhining
ro.build.host=srv-pad-compile5
ro.build.tags=test-keys
ro.product.model=GS705B
ro.product.brand= Android
ro.product.name= Demo_7051H
ro.product.device=snk
ro.product.board=atm7051H_demo_q88_hd
ro.product.cpu.abi=armeabi-v7a
ro.product.cpu.abi2=armeabi
ro.product.manufacturer=Actions
ro.wifi.channels=
ro.board.platform=ATM702X
ro.build.product= Demo_7051H
ro.build.description=Demo_7051H-user 4.4.2 KOT49H eng.songzhining.20161121.190628 test-keys
ro.build.fingerprint=Android/Demo_7051H/q88_hd:4.4.2/KOT49H/eng.songzhining.20161121.190628:user/test-keys
ro.build.characteristics=tablet 

のように、GS705Bというタブレット用の開発環境がそのまま流用されているようです。うわぁ。

要するに、これはジョイスティックのついたAndroidタブレットです。
(悪口ではないですよ。)


bootlogを見ると、どうもブートローダはu-bootではないようです。
vfatフォーマットの/miscパーティション内に置いたboot.imgからkernelを起動出来たり、結構便利な感じですね。

f:id:honeylab:20191114103831p:plain

起動ロゴっぽいbinとかもあるので、ファームウェア自体にあまり手を触れず、
結構遊べそうな感じです。

そして、肝心のエミュレータですが…

f:id:honeylab:20191114104014p:plain

 「mvsnjemu」ですね。NEOGEO miniと一緒だね。
GPLだね。よろしくね。

 

何かしらのグラフィックのアクセラレーションが効いてるんじゃないかと思うんですが、まだその辺は確認していません。
mvsnjemu内にSDL_INITがいたので、その辺を使えば普通に効くのかしら。

なんかしら適当なのを適当に持ってくればなんでも動きそうな気がします。
バイス周りは絞ってると思うのでできればカーネルを再コンパイルしたいところではありますが…

 

そして、気になってる人も多いと思う隠しゲーム。
順次アンロックになるので外部からゲームファイルを供給するのか、フラグ解除方式なのかという話でしたが

とりあえず、内部に全ゲームROMは収められていることはわかりました。
また、私レベルのユーザであれば自分でアンロックもできることはわかりました。
それ以上は、記録に残すことはやめておきます。(うざい)

 

とりあえず、カーネルのソースお願いね!

 

 

NEOGEO Arcade Stick Proを開封レビュー

開封とは…

f:id:honeylab:20191113140442j:plain

裏ブタを外すと、思ったより小さいメイン基板が現れます。

 

f:id:honeylab:20191113140549j:plain


基板下側の4ピンにRX/TXって書いてあってバレバレじゃんププーとか思ったんですが、今のところここから出力は出ていません。
なので、何のOSが入ってるかとかそういうのも今のとこ不明。
左上にも4ピンがあって、ここの役割はまだわかっていません。
B1を押しながらUSBを挿すとファーム更新モードに入ってるっぽいですが、
デフォルトのUSBケーブルで反応してません。あ、ケーブルが違うのかな?

f:id:honeylab:20191113140744j:plain

CPUはActions SemiconductorのATM7051H。

NEOGEO MiniにはATM7013っていうのだったので、たぶん同系統。
NEOGEO Miniのはカスタムファームが出てたので、こいつもいけないことはないと思うんだけど、まだそこまでは手付かず。

 

 

ストレージはEMMC。本気ならはがして読めるんじゃない?俺はやらない。

f:id:honeylab:20191113141114j:plain

基板裏。 NEOGEO G1 V4.4 なんでもうV4なの?

 

f:id:honeylab:20191113141023j:plain

 

とりあえず蓋を戻した。ちゃんと動いた。

これからもうすこし頑張って解析してみます。

解析して、手に負えないようなら手放します。

 

メガドライブミニに一般的なUSBアーケードスティックを直接接続して使えるようにする

メガドライブミニが発売されて2週間。

いろいろなハックをしてきましたが、やっておきたかったこの改造が成功したので記録しておきます。

(※この記事の内容は技術的検証であり、完全に再現可能な手順を記したものではありません。この手順で行ったことをもとに、平均的なユーザが利用可能なツールがリリースされる可能性はゼロではありません。平均的なユーザが、現在できることではそのリリースを待つことです。)

 

過去の記事にも書きましたが、メガドライブミニではいわゆるファームウェアLinux)の設定で、特定の公式サポートゲームパッドしか接続・認識できないことがわかっています。

honeylab.hatenablog.jp

また、偶然USBのVIDやPIDが一致したパッドでも、上下左右のキーが正しく入力できなかったり、ボタンのマップがめちゃくちゃで、ろくにゲームができない、という状態のようです。

そんな中、

www.4gamer.net

このような製品もサードパーティから発売されるようで、一般的なユーザはこの変換アダプタを購入して使用するのがいいのではないか、と思われます。

しかし、これ一本 5,480 円するようで…
処理内容を考えると、全く妥当ではあるんです。しかし、じゃぁこれを使ってアケコンで対戦する、となったらx2本で一万円かかってしまうわけで。

もちろん、それも一つのやり方ですが、ここはメガドラミニのほうを書き換えて
一般的なアケコンを使えるようにしてしまえ、というハックが成功しました。

 

使用したアーケードスティック

 今回使用したアーケードスティックは、iBUFFALOの「ARCADE STICK 13Ⅱ」

(BSGPAC02BKBC)というものです。
近所のハードオフのジャンクコーナーにありました。

ジャンクコーナーにあったので、動作が不安だったのですが、どうやらボタンやスティックが前オーナーによってマルっと交換されているだけで、動作には問題はありませんでした。
ボタンの交換がジャンクコーナー行きの理由だったようです。

 

どうやってつくったか

メガドラミニの内蔵謹製エミュレータがどのようにしてコントローラ入力を読み取っているのかをまず観測してみます。

Linuxシステムコールの呼び出しを観測できる「strace」ツールをメガドライブミニに入れて動かしてみます。

# /rootfs_data/strace -e trace=open -ff /usr/game/m2engage

すると、

[pid 29051] open("/dev/input/event4", O_RDONLY|O_LARGEFILE) = 8

という部分が見つかりました。
どうやら、/dev/input/event4を読んでいるようです。

 このデバイスは、Linuxソースコード evdev.c をHUBのポート番号によって番号が固定されるようにオリジナルのソースから改変することで実現されていました。

 

純正のメガドライブパッドを接続したとき、event4がどのようなイベントを受け取っているのか、「evtest」ツールで確認します。

 Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0xca3 product 0x24 version 0x111
Input device name: "6B controller"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 288 (BTN_TRIGGER)
Event code 289 (BTN_THUMB)
Event code 290 (BTN_THUMB2)
Event code 291 (BTN_TOP)
Event code 292 (BTN_TOP2)
Event code 293 (BTN_PINKIE)
Event code 294 (BTN_BASE)
Event code 295 (BTN_BASE2)
Event code 296 (BTN_BASE3)
Event code 297 (BTN_BASE4)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 127
Min 0
Max 255
Flat 15
Event code 1 (ABS_Y)
Value 127
Min 0
Max 255
Flat 15
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN)

出力は上のようになりました。
ボタンは、288-297がレポートでき、方向キーは、X軸、Y軸それぞれ0-127-255の絶対座標で受け取れるようです。 

では、この買ってきたアーケードスティックを接続した場合はどうなるでしょうか。

…… なんと、当然認識しません。カーネルにIDが記録されていないからです。
この辺の制限を外したカーネルを使って試す必要があります。

制限を外して再コンパイルしたカーネルを使うと以下のように認識させることができます。

Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x1dd8 product 0xe version 0x110
Input device name: "BSGPAC02 Series"
Supported events:
Event type 0 (EV_SYN)
Event type 1 (EV_KEY)
Event code 304 (BTN_A)
Event code 305 (BTN_B)
Event code 306 (BTN_C)
Event code 307 (BTN_X)
Event code 308 (BTN_Y)
Event code 309 (BTN_Z)
Event code 310 (BTN_TL)
Event code 311 (BTN_TR)
Event code 312 (BTN_TL2)
Event code 313 (BTN_TR2)
Event code 314 (BTN_SELECT)
Event code 315 (BTN_START)
Event code 316 (BTN_MODE)
Event type 3 (EV_ABS)
Event code 0 (ABS_X)
Value 128
Min 0
Max 255
Flat 15
Event code 1 (ABS_Y)
Value 128
Min 0
Max 255
Flat 15
Event code 2 (ABS_Z)
Value 128
Min 0
Max 255
Flat 15
Event code 5 (ABS_RZ)
Value 128
Min 0
Max 255
Flat 15
Event code 16 (ABS_HAT0X)
Value 0
Min -1
Max 1
Event code 17 (ABS_HAT0Y)
Value 0
Min -1
Max 1
Event type 4 (EV_MSC)
Event code 4 (MSC_SCAN) 

試してみると、ボタンは304~316、で、X-Y-ZとHATが使えるようです。
詳しく調べてみると、このコントローラ、「mode」ボタンで x-yモード、zモード、HATモードが切り替えられるようです。今回は、x-yモードを使います。

アーケードスティックの「1」~「10」を順に押していき、割り当てを確認します。

すると、「BTN_B,BTN_C,BTN_TR,BTN_TL,BTN_A,BTN_X,BTN_Z,BTN_Y,BTN_SELECT,BTN_START」のように割り当てられていることがわかりました。

これをメガドライブ純正パッドと同じようになるように変換してやればいい、ということです。

では、それをどうやって実現するか。

まず、標準のカーネルでは/dev/input/event4~event13に割り振られる部分のソースコードを変更し、+10して event14~event23に割り当てられるようにします(退避させる)

 

そこで、LinuxのUsermode Input Deviceという機能を使い、イベントコードを変換するプログラムを書きます。

具体的には、以下のようなソースコードです。

 

bitbucket.org

 

 このへん

qiita.com

を参考にしています。

 

 

このソースコードを、ホスト上でメガドライブミニ用にコンパイルし、メガドライブ上にコピーします。

iBuffaloのアーケードスティックをメガドライブに接続すると

[50270.421860] generic-usb 0003:1DD8:000E.0007: usb_submit_urb(ctrl) failed: -1
[50270.429714] generic-usb 0003:1DD8:000E.0007: timeout initializing reports
[50270.437645] input: BSGPAC02 Series as /devices/platform/sunxi-ehci.1/usb1/1-1/1-1.2/1-1.2:1.0/input/input14
[50270.449359] generic-usb 0003:1DD8:000E.0007: input,hidraw0: USB HID v1.10 Gamepad [BSGPAC02 Series] on usb-sunxi-ehci-1.2/input0

という表示が現れ、

# ./evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: axp22-supplyer
/dev/input/event1: sunxi-keyboard
/dev/input/event2: gpio-keys
/dev/input/event3: sunxi-ths
/dev/input/event14: BSGPAC02 Series

 

event14(本体のコントローラポート1に挿したため)が割り当てられました。

先ほどのプログラム(uinput)にこれを引数として渡します。

# ./uinput /dev/input/event14 &
# argv[0]=./uinput
[43017.030912] input: evfrom23 as /devices/virtual/input/input36
argv[1]=/dev/input/event14 

 すると、/devices/virtual/input/input36という仮想inputデバイスが作成され、プログラムで変換した値が送信されるようになります。

この時作成された仮想inputデバイスは、たまたまうまいことevent4に再マップされました。(udevルールを書くことで確実になるはずです)

# ./evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0: axp22-supplyer
/dev/input/event1: sunxi-keyboard
/dev/input/event2: gpio-keys
/dev/input/event3: sunxi-ths
/dev/input/event4: evfrom23

 この状態で、内蔵謹製エミュレータを起動すると、見事iBuffaloのアケコンを認識し、操作ができるようになりました!!!!

 

ここまで、手作業で実行して確認しているので、この一連の流れをスタートアップスクリプトとしてrootfsに書いてやれば、自動的にアーケードスティックを認識できるようになるはずです。

また、今回変換テーブルを作らず直接変換してしまっています。
そうではなく、接続されたコントローラのVIDなどを見て、適切なマップを追加することで別のコントローラも使用できるようになります。
専用の設定ファイルでも作ってやると後々追加出来て便利なんですかね。

加えて、現在のところ、本体にはんだ付けしたシリアルコンソールを利用しないで、
カーネルを書き換える仕組みがまだ整備されていません。
おそらく海外のproject LUNARやhakchiチームがそのあたりを実装したら、
そのコードを利用することで、本体を(物理的に)無改造でこのような動作をさせられるようになるはずです。しかし、保証は外れそうなので、その辺気になる方は、最初に出てきた変換アダプタを使うのがいいんでしょうね…

さて、この方法でメガドライブミニをプレイしている証拠映像がこちらです。

 


メガドラミニにアーケードスティックをつなぐデモ

 

デモ撮影中とはいえゲームへたくそすぎんだろ…
まぁ、波動拳出てるんで、ちゃんと動いてるんだと思いますよ。

 

見た目ではわかりませんが、基板乗っ取りやArduinoなどの変換アダプタは使用していません。
メガドライブミニに直接コントローラのケーブルを挿しているだけです。

遅延など、測定はしていないのですが、本当に必要になったらどうにか測定してみたいと思います。
外付けUSBデバイスで変換するよりは理論上早いはずなんですがね…

 

メガドライブミニ(Genesis Mini)の前面イヤホン端子とボリュームつまみを使えるようにしました!

メガドライブミニ、精巧なモデリングが評判でしたが、
どうしても再現できなかったと思われる前面イヤホン端子。

それを恒例の魔改造で使えるようにしました!

メガドライブオリジナルには3.5mmのイヤホンジャックがついていましたが、
同じものをつけると明らかにでかすぎたので、ちゃんとミニ化して2.5mmのをつけてます。

なので、普通のヘッドホンを繋ぐには変換ケーブルが必要です。

また、技術的な都合もあり、なんと元のメガドライブに使用されていたのと
同じアナログオーディオICを使うというひとネタもあり。

f:id:honeylab:20191006102502p:plain

 

もっと詳細な作成技術情報はこちら

https://www.slideshare.net/ssuserb6da59/ss-179366684

 

簡単に言うと、CPUからHDMIに送られる途中のデジタル音声信号を分岐し、
アナログ変換して、

 


ボリュームつまみの信号で音量も調節して、

f:id:honeylab:20191006102841p:plain

ヘッドホン端子のところに穴を開けて
めちゃ配線して

 

f:id:honeylab:20191006102914p:plain

こうじゃ!!

 

youtu.be

どや。