honeylab's blog

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

令和カラオケ羅生門まとめ

ジャパニーズ文化代表のカラオケ

テープ、8トラから始まり、LDをとともに日本のカラオケ文化を牽引した通信カラオケ

この通信カラオケの技術の礎となったのは、DTMでよく使われるMIDI音源

MT-32やSC-55、88、XG音源など、パソコンやゲームの界隈では一般的な外付けモジュールとして目にする機会は多かったものの、通信カラオケでそれがユーザーの目に触れる機会は多くありませんでした。

なぜなら相手は業務用機器。カラオケコマンダは定価では数百万円する上、一般流通にはあまり出てきません。しかしいまはヤフオクで過去のカラオケ機材が数千円で手に入ってしまうため、マニアの格好のオモチャとなりつつあります。

 

私が以前分解して同人誌にあれこれまとめたDAMのカラオケ

honeylab.booth.pm

DAMシリーズは、YAMAHAと共同開発が行われているため、基本的にXG互換のMIDIデータ、音源が使用されていますが、特定の型番はいまだに明らかになっておらず、珍しくこちらのYoutube動画でその姿を見ることができます。

https://www.youtube.com/watch?v=ArYog2T7fRM

このモジュール、実機の音源基板がそのまま収められていると思われ、また、XG1000の本体ソフトウェアの解析結果から、単体でもおそらく鳴らすことができるはず、ということを前々からみんなで言ってはいたのですが、なかなか実現までやってみるか、という人が現れずにいました。そんな中、XG1000の遠い先祖である、DAM-6400に内蔵されている音源を単体再生できたという知らせが。

上記のように、音源基板を取り出して適切にMIDI信号を突っ込んでやると、見事に音が鳴ったとのことです。

ちなみに、XG1000ぐらいの世代のカラオケ機では、本体がLinuxで動作しており、USBデバイスとしてFPGAで構成されたマルチポートMIDIバイスが存在し、その先では普通に312500kbpsのMIDI信号が流れている、という構造になっています。
音源チップからでる信号ははデジタル(I2Sみたいなの)なので、そのデコーダがボードに載っていない場合はDACを外付けしないと音が鳴りません。

 

続いて、DAMシリーズの中で大変異色な機種「G70」というのがありまして、こいつ、シリーズの中でなぜか、本当になぜか内蔵基板がRolandになっているのです。


そして、過去に分解された情報から、SC-88Pro相当のものが入っている、という噂がありました。

 

それを元に分解アタックされた結果、見事にその通りで、やはり単体音源として再利用可能だったようです。

 

 

特にSC-88Proは音源セットなどの関係で需要があるようで、ヤフオクで今まで1円でも売れなかったようなG70のガラクタがなぜか突然売れ始める、という現象が起きているとのことです。

ってハチプロ高!!

この辺も、実際カラオケはハチプロの音がするよなー、でもほんとかなー、って思っていた人たちが、中身をちゃんと見てやっと本当にハチプロだった!ってってるのがおもろいよね。

 

そんな感じで盛り上がっていたので、せっかくなので私ももっと古いやつから音源ボードを剥いで動かしてみました。

ターゲットはVictorの孫悟空Rolandと書かれたMIDI音源ボードが刺さっていました。

 

 

ピンを適当に当たったり、Rolandの他の音源のサービスマニュアル・回路図などを参照すると、どうやら簡単にMIDI音源化できそうです。

 

 

DACを持っていなかったので、同じVictorに載っていたやつを剥がして繋いだのですがなぜか音がしない・・・


仕方ないので、別の古い機体、JOYSUNDのMJ-10にもRolandの音源が載っていたので、それの先につながっていたDACを繋いでみたところ

 

見事再生成功。

 

音源に対して音色セットの要求をしてみたところ、SC-88無印相当までの音色が入っていたので、これは88相当の音源なんだと思います

 

ところで、、、載っている「RA09-002」というチップは「XP6」という名前で各種Rolandの音源や楽器に使用されています。この型番で調べていたところ、こんなものを見つけました。

www.vogons.org

なんと、このカラオケ音源内蔵モジュールを引っこ抜いて、DACをつけ、USBMIDIとセットで製品として中国で売られていたというのです!

https://www.vogons.org/download/file.php?id=193135&mode=view

すげぇぇwwwさすがすぎるwww

いや、先にやられてたのちょっとショックだわ。っていうか、インターネットとかでこういうふうに情報が出てくるよりももっと前に、これをできる、って作っている人たちはいたんですねぇ。すごいすごい。

この変な製品に入っている基板には「02ーSC-NK」と書かれています。ほぼ同じ部品が使われたバージョン違いの「01-SC-VI」を私は持っていました。SCはきっと「SoundCanvas」のことおそらくNKはカラオケ「BeMax」をリリースしていた「日光堂」、そして「VI」はこの「孫悟空」をリリースしていた「Victor」の略だと思われます。基板自体も本体の他の基盤とはプロセスで作られているように見えますので、Rolandは業務用としてたくさん音源モジュールをOEM製造していたんですね。おもろいおもろい。

 

さて、こんなふうに過去のカラオケ基板の生きているかもしれない体から音源ボードだけモイで遊んでいる姿を見ていて、ふと老婆の声が聞こえてきませんか。

 

「この板を抜いてな、この板を抜いてな、音源ボードにしょうと思うたのじゃ。」

iOS+SwiftUIでBLEアプリとESP32でBLEペリフェラルを作っていてハマったところ

 

仕事でBLEペリフェラルバイスと、それに繋げるアプリを作っていて、
自分で作ったBLEデバイスに絞ってパッと一覧を出したかったので、

https://zenn.dev/tomo_devl/articles/d58abecf10c599

に書いてある

scanForPeripherals(withServices:options:) を使用するとペリフェラルを検索でき、stopScan() を使用するとペリフェラル検索を停止させることができます。
サンプルでは接続されているかどうか確認し、されていなければペリフェラルを検索しています。
scanForPeripherals の withServices にUUIDを指定してあげれば特定のペリフェラルに絞ることができ、nil を指定してしてあげればすべてのペリフェラルを検索することができます。

を実装したところ、全く思った通りに動かなかったので仕方なく名前とかの検索で進めてたんだけど、流石に不便で、接続してサービスを取得する、を繰り返す、しかないのか???と思ってたんだけど、デバイスペリフェラル)側のサービス一覧に載せるだけではなくて、
アドバタイズパケットの提供サービスのところに記述を追加しないとセントラル側からはサービスがあるかないか、接続しない限りはわからないのだった。

今はBLEのパケットについて一通りわかったのでそうわかれば納得だが、始めた頃に手探りで実装していたので全然気づかなかった。

このへんの流れを書いてある系の記事を何個か見たけど、そこまで書いてあるところには辿り着いてなかった。大体はすでにできてるデバイスのわかってるアドバタイズを拾えば十分だからだろう。

 

記述例(ESP32 Arduino

// Create the BLE Service
// このサービスは接続してからしか取得できない
BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID_XXXXX),32);

// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY);
// pTxCharacteristic->addDescriptor(new BLE2902());

BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
  CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE );

pRxCharacteristic->setCallbacks(new MyCallbacks());
InitBLEParams(pService,new MyCallbacks());
 
pService->start();
// Start advertising
pServer->getAdvertising()->addServiceUUID(SERVICE_UUID_XXXXX); // アドバタイズパケットに載せる
pServer->getAdvertising()->start();

 

iOSアプリ側

centralManager.scanForPeripherals( withServices: [serviceUUID], options:  nil)

ESP32側でaddServiceUUIDをしておかないと、withServicesをnilにしないと検索されない

 

ーーーーーーーーーーーーーーーーーーーーーー

珍しくプログラムのこと書いてるけど、まぁ、そういうのも書いといた方がアクセスあるかもだし、と思ってこういうこともこれから書くことにしてみる。
毎日分解ばっかりはしてられないらしい。

SHEINで子供用カメラを買ったら爆発寸前だった話

あえてタイトルにこう書いてますが、まぁSHEINに関わらず国内外どこで買ってもついて回る問題ではあるんですよね。

嫁が子供用にSHEINで発注してくれていたんですが

(ウチの兄妹になんか買う時には必ず二つ買っとかないと大喧嘩するので水色とピンクの2つ)、

渡す前に電源はなんだっけ?と確認したら充電式のよう。ではチェックしてみるか、と開封してみたところなんとよりによって兄の分の水色のやつ、電源が入らないことに気づきました

 

Image Image

 

こういうもの、子供に渡す前に一旦チェックしておかないと大変めんどくさいことになるんですよね。

たとえばこんなのとか

ピンク色の方は電源も入るし、USBコネクタを刺すと充電されていました。

しかし、水色の方は電源が入らず、USBコネクタを挿しても赤ランプが点灯し、充電アニメーションが起きません。

内蔵バッテリーが劣化しているか、断線などが起きていて充電されないのでは、という野生のジャンカーの勘が働き、SHEINで不良申告したところで次いつ来るかもわからんし、とりあえず開けてみるか、と精密ドライバーでネジネジImage

ぱっかーん

 

あああああああw電池パンパンwwwww

過充電か過放電、もしくは初期不良により妊娠状態です。これは危ない

慎重にバッテリーを両面テープから外して配線を切断し、たまたま庭に掘っていた穴に埋葬します。こうしておけば自然に大地によって放電され、危険のない状態になる気がします。

 

手持ちの在庫を調べたところ、たしかDAISOのBluetoothスピーカーに入っていたような気がするLiPoがあったのでこれと交換することにします。入るぐらいの大きさってことは、充電回路も大差がないはずですImage

交換して充電したところ

復活!

Image

 

SDカードを入れなくても内蔵領域で多少撮れるれるようです。

 

で、SDカード入れて撮影解像度を1080pにするとこんな感じ

1080pとは!!!!(左下のタイムスタンプを見ると画像がちゃんと1080なのわかるね!!)

 

ところで、USBケーブルで繋いだときにどうやらPCカメラとして認識してくれることが発見されましたがImage

残念ながらそういうふうには動いてくれないようでした。ざんねん!

Imageいやぁ、爆発しなくてよかったねぇ。

 

DDRminiで自前ビルドのMAMEが動いた!

ここまでのまとめ

 

honeylab.hatenablog.jp

 

さて、すでに分かっているように、こいつの中にはZUIKIの手下の開発会社がカスタムしたDDR専用のMAMEがインストールされています。
完全にそれ以外を除去したわけではありませんので、それ以外の関連のゲームは少しの手直しで動作させることができる可能性があります。

しかし、それ以外のゲームを動かすためのコードは入っていない可能性がありますし、通常のMAMEで使用できる各種機能やパッドのカスタマイズなどは使用できません。

この機械、8コアのARM64が入っているというこの手の機器としてはかなり高性能な演算機能を持っていますので、エミュレーション性能もかなり高いはずです。

それを利用するために、どうにかしてMAMEを入れてみたいところでしたが。

MAME全然わからんw

さらにクロスビルドということもあって全然わからん。

あちこち探したところ、似た環境のARM64であるRaspberryPiように一発でMAMEをクロスビルドしてくれるツールキットを見つけたのでこれを使ってみました。

github.com

途中、変な制約につかまってまともにコンパイルできるまで2日ほどかかってしまいましたが、最終的に見事動作する環境を作ることができました!

 

音声・音量周りの調整ができないなど不便な点はまだまだ残っていますが、HDMIも簡単に使用できるため結構なんでもできる気がします。

これだけ動くDDR筐体の形をしたMAMEマシンなら、まぁクッソ高いわ!というところから、ちょっと高いかも、ぐらいまで楽しめるんじゃないでしょうか。

とりあえずは、DDRBEMANIシリーズがどのぐらい動くのかは気になるところです。

ただし、内蔵のMAMEシュリンク版)は、ver0.24ぐらいからのフォークっぽく、一応は謹製扱いのパッチワークがされていると考えると、もしかしたら内蔵のやつの方が再現度が高かったりするんでしょうか。わかんないですけど。

まぁ、本当に必要ならバックポートしたらいいんだと思うんですけどね。逆アセンブルするしかないけど。

 

で、動きました、とはいうけど、残念ながらみんながみんなぱっとインストールできる状態にはなっていません。少なくとも私はSDカードのはんだ付けからrootfsを書き換えて、USBへのバックドアを作っています。

それに対して、いつものようなFELモードでの書き換えの道も開かれたようです。

 

これを使えば、はんだ付けなし、本体を分解して基板を開いてボタンを押しながらUSBを接続してインストール、という手順でインストールすることができるようになるでしょう。それまで、もうちょっとだけこの戦いは続くんじゃ。

DDRMini解析まとめ

honeylab.hatenablog.jp

honeylab.hatenablog.jp

honeylab.hatenablog.jp

上の3つの記事と私のTwitterで随時解析情報をお知らせしてきましたが、一定の成果を

得られたためここに記しておきます。

 

ハードウェア、ファームウェアについて

・CPUはAllWinnerの8コア 2.0GHz A572という割と豪華な奴

・ストレージ8G,うち2GをゲームROM含むrootsとして使用

Linux Kernel 5.15

Linux version 5.15.123-yocto-standard (oe-user@oe-host) (aarch64-poky-linux-gcc (GCC) 11.2.0, GNU ld (GNU Binutils) 2.38.20220313) #1 SMP PREEMPT Mon Jan 29 02:33:21 UTC 2024

一応サポート情報のOSSからダウンロードしたソースコードコンパイル可能ではある

・が、書き換えて動く保証はない(BROMでの検証がきつい)し、ENVを書き換えてLinuxコマンドラインを改変しようとしたら文鎮化した。

・eGON ヘッダバージョンが4.0

・u-bootはtina 2018-07ベース

・rootfsについては特に検証されていないので書き換えは可能

・SDカードスロットのパターンがあるので、これにSyterKitというツールキットで作ったブートローダやベアメタル実行ファイルを書きこんで動かすことが可能(mmc0)

・これで実行ファイルを作り、ROOTFSをフルダンプしたうえで、initスクリプトUSBメモリのマウントとシェルスクリプトを読み込むようなバックドアを書き込み、システムを自由に書き換えることに成功した。

 

 

・↑SDカードスロットと配線のはんだ付けが必要

 

・↑はんだ付けを必要としてないFELモードからの独自バイナリも起動できるらしいが、私はまだ試していない

 

・普通に使えるシリアルコンソールは出ていないが、DTSを定義するなりレジスタを設定するなりすれば使える2系統は出てるっぽい。

あと、SDカードをあきらめればPF2,4も使えるのかも。

・ハードウェアシリアルを復活させるのは一寸めんどいけど、Linux起動後であればUSB Serial Gadgetをコンパイルして読み込ませ、gettyを起動するようにすれば起動後にはシェルに入ることができるようになる。passwdの書き換えが必要

 

ソフトウェアについて

・メニュー画面の実行ファイルとエミュレータ部分の2つに分かれている

ゲームエンジンMAMEベースのエミュレータ。ベースっていうか、DDR以外の部分を削ったものに独自パッチとROMの暗号・復号化ルーチンを付け足したり、デモの制御などを行うための改変が行われている

 

・DDR2ndMIXの未収録曲は、ゲーム用CDDAのCHDのトラックを無音化することで鳴らないようにされている。白看板はMAME改側で対応。

 

・そのほか付属のROMはおそらくMAMEのROMセットと全く同じものらしい

 (ただし、暗号化されている)

 

・暗号、複合ルーチンは解析済みのため、必要であればCHDの中身を書き換えるか、拾ってきて(ダメ)差し替えるだけで選曲・ステージで鳴らすことができる。白看板を消すにはプログラムへのパッチが必要

 

・本来MAMEでエミュレーションするときには基板のセルフチェックを通るため時間がかかるが、収録時に通過後に保存したステートセーブを読み込んで起動している

・3rdMIXも同様にデータが削られているような気がする。加えて、起動時に本体内に音源データをプリロードしているのでステートセーブを読まないようにしたうえで、CHDを差し替えると読み込まれた時点のデータがロード、再生される(ような気がする)。追加でプログラムにもパッチが必要かもしれない。当てたものが↓

 

・USBでファームアップがあったが、この手法で曲が追加される可能性はゼロではない。ゼロではないが。

 

というわけで、少なくとも私のDDRMiniは、再生できない曲が無音で足譜だけ流れるような残念な状態ではない状態にすることができました。

しかし、まぁ権利の問題でこうなっているので、これをあれこれするようなことをこれ以上私からどうこうすることはできないのです。

しかし、筐体の出来やLEDの演出は大変よく作られていて、ゲーセンに通いまくっていた青春時代を思い出させてくれるとても良い飾りだと思います。

あとは、そうね、普通にaarch64なのでそれ用のMAMEなりStepManiaコンパイルして突っ込む、ことは可能かと思いますので、追々やっていきたいと思います。まずはここまで。

 

DDRMini 作業ログ

Avaota-SBCというDDRMiniにかなり近い構成のボード用にビルドしたバイナリが断片的に動くので、これを使ってファームウェアを吸い出しつつ、逆アセンブルを続けているところではあります。

 

・UART0(PB9,PB10)が明確にデバッグ用に出ているがLinuxの先ではDTSで無効化されているのでほとんど何も出てこない。が、最初のBOOTの間はdの先行入力でちょっとだけメッセージが出る。

Image

 

・BOOT0 (emmc上0x2000)がboard_initした後、MMCからTOC1パッケージを読み込んでいる。このへんはこの二つのページの機材がよく似ている。

Allwinner H700 Firmware extraction - KNULLI Wiki

Teclast P85T - linux-sunxi.org

・上にあるように、u-bootのエリアがあるけど実はu-bootじゃないのかな、と思って読み込んで逆アセンブルしているけど、本当にu-bootっぽい。

「U-Boot 2018.07-00009-g40a0e96-dirty (Jul 24 2024 - 13:19:23 +0800) Allwinner Technology」

このツリーは、ベースの2018に山ほどのパッチをしてようやく動かしているものらしい。

・このTOC1がemmcのbootパッケージから!ANDROIDを読んで起動している

 

・その次のパーティションがrootfs、ここにゲームもROMも入っている

Image

・ゲームのROMは独自の暗号化がされている。

Image

・rootfsを書き換えるだけである程度動かせるとは思うけど、現状何も出力できないしシェルにログインできないので大変やりにくい

・どうにかシェルを使うためシリアルコンソールの有効化を試みている

・UART0はLinuxのDTSで無効化されているので起こすのは難しい

・配線を辿るとUART2もつながっている。

 

・ENVのパラメータをいじればttyS2でコンソールが起きるはず

・ENVをいじって書き戻そう!

・書き戻した

・壊れた。

 

壊れた。

 

書き戻す場所を間違えたのか、値がおかしいのか。

もっかいeMMCのフルダンプを取ってどこを壊したのか調べてみる。

 

遠い。

DDR miniのハッキングがいよいよ本格的に始まった

honeylab.hatenablog.jp

分解して下調べをしていたDDR mini

既にファームウェアアップデート用のUSBを探しそうな画面が発見されていますが、
これは適当にUSBを挿せばいいものではなく、必要な条件のもとパッケージングしたものに対して発動するものだと思われます。

 

 

その条件を調べることや、他にバックドアがないかどうかを調べるため、内部のソフトウェアを調べていきます。

で、どうやって?

まず、このAllwinnerのCPUは、FELモードというUSB経由であれやこれやするためのモードが備わっていますが、ここで行うことができるのはプログラムの転送ぐらいです。
まずFELモード上でu-bootなどのブートローダを転送して実行し、そのあとファームウェアを転送して書き込んだりすることができます。
過去にさんざん弄ったファミコンミニの系列はこの方法でカーネル書き換えが進められてきました。

www.ns-koubou.com


しかし、今回採用されたA527というCPU、かなり新しいもので従来使われていたようなu-bootが対応できていないようで、まともにコンパイルできるツリーが見つかりませんでした。そのため、何か他の方法を使わなければなりません。

いろいろ探していたとこ、A527やその互換のT527というCPUを搭載したAvaotaSBCというオープンソース設計の組み込みボードがあるのを見つけました。

github.com

また、それに対応したベアメタルの開発環境、そしてブートローダLinuxの入ったOSイメージがあります。これが使えそうだと踏んで調査を行いました。

github.com

github.com

Allwinner系のCPUの多くは、起動シーケンスとしてeMMC(8bit onboard SDC2)のほかに、SDカード(4bit SDC0)やSPI Flash、NAND等いろいろなストレージから起動できます。

A527は都合がいいことに、基板上のeMMCより先に、今回基板上からオミットされたSDカードスロットから起動することがデータシートに記載されていました。

 

そのため、まずSDカードスロットを復活させました。
しかし、SDカードソケットを付けてもそのままでは使えません。
きちんと使えないように、各信号線が基板上で分断されていますので、そこをすべてジャンパし、またCLK以外の線は10Kオームでプルアップする必要があります。

 

この配線を行い、SDスロットの信号を見ながら電源を入れるとCLK信号が観測され、SDカードを探しに来ていることが確認できました。

 

次はSDカードの中身の準備です。

先ほど見つけたベアメタルの環境をコンパイルし、テストコードをいくつか書いてみます。

一応動いているようですが、動いた結果が観測できません。
なぜなら、標準入出力であるシリアルポートが発見できていないからです。

今までのミニコンソールは、それっぽいところを当たりながら電源を入れればすぐにブートローダLinuxのメッセージが表示されていました。が、今回は徹底的にその動作が潰されていて、全く信号が確認できません。

とはいえ、シリアルの配線は絶対に残っているはずです。

 

データシートとピンアサイン、そして基板上の配線を穴が開くほど見つめながらプログラムを調整したところ、見事にシリアルポートをの出力を確保できました。

 

プログラムが動いたらこっちのもの。eMMCの中身を読み込み、SDカードに保存して解析すればいいのです。

というわけで、先ほどの環境からSDカードを使っているサンプルを改造し、実装してみましたが。。。。。動かん。っていうか、動きが変。

 

どうやら、SDカードとeMMC、どちらかしか使わないと仮定してあり、各パラメータを保存するメモリを一つ分しか確保しないコードになっていました。

github.com

これを修正し、カード二枚が同時に使えるようにしたところ、無事、eMMCとSDカードどちらからも読み込めるようになったんですが・・・・書き込めない!!!!

さんざん悩みつつ調べた結果、書き込み部分が実装されていませんでしたw

というのは一寸違ってて、実はSDカードの伝送、高速化のために普通はDMAによるメモリ転送を使い、まとめて転送するようになっています。

今回のベアメタル環境、DDRMiniの環境と完全に同じではないため、基板上のDDRメモリの初期化が行えず、大きなメモリ空間やDMAが使えない状態でした。
そのため、DMAではなくFIFOに1バイトずつ書き込む”CPU転送”モードを使う必要があったのです。サンプルソースのドライバでは、DMAの部分は読み書きどちらも実装されていましたが、CPU転送、レスポンスの読み込みにしか使わないので書き込む部分は省略されてたんですね。気づくのにしばらくかかりました。


Linuxのドライバのソースなどを参照し、この部分を実装すると、見事eMMCの内容をSDカードに書きこむことができるようになりました。

 

書き込めたらこっちのもの。中身を調べていきます。つづく。