HN 日本語サマリー

← 一覧へ戻る
プログラミング

NEC V20 マイクロコードのデコード

Decoding the NEC V20 Microcode (martypc.blogspot.com)

35 pointsby mariuz0 コメント

要約

この記事では、NEC V20 CPUのマイクロコードを抽出・解析するプロセスについて詳述しています。高解像度のCPUダイ写真とMaskRomToolなどのツールを使用し、最終的には畳み込みニューラルネットワーク(CNN)を用いてマイクロコードのビットを識別・抽出することに成功しました。これにより、NEC V20の正確なエミュレーションへの道が開かれました。

全文翻訳

NEC V20 マイクロコードのデコード リンクを取得 Facebook X Pinterest Email その他のアプリ 2026年9月3日 reenigne による 8088 マイクロコードのデコードは、2020 年に極めて正確な 8088 CPU のエミュレーションへの扉を開きました。MartyPC に NEC V20 のサポートを追加していましたが、V20 コアは V20 の実際のタイミングに関してサイクル精度ではありませんでした。それは V20 の服を着た 8088 でした。私の 8088 コアのコピー&ペーストに V20 命令を追加しただけでした。 これは理想的な状況ではありませんでしたが、マイクロコードなしで V20 コアをサイクル精度にするという見通しは、試行錯誤による気が遠くなるような作業になる可能性がありました。 では、なぜマイクロコードを入手しないのでしょうか? 最近、InfoSecDJ に NEC V20 CPU (実際には Sharp 製のセカンドソース V20 ですが、V20 であることに変わりはありません) のダイ写真撮影を依頼しました。彼は素晴らしい仕事をしてくれました。 NEC V20 CPU ダイ - InfoSecDJ このフォトモザイクは非常に高解像度です。正確には 5.6 ギガピクセル、驚異的な 70478x80672 の解像度で、JPEG 画像形式に収まりきらないほどです! 全体をフル解像度でこちらで見ることができます。 ダイの中央よりやや下の長方形の領域が、メインのマイクロコード ROM です。 V20 マイクロコード ROM ブロック ROM アレイは 258x116 で、29,928 ビットを含んでいます。これは 29 で均等に割り切れます。これは V20 のマイクロコードワード長であることがわかっているので、良い兆候です。しかし、これは 1032 マイクロコードワードを意味しますが、私たちは 1024 しか期待していませんでした。少し奇妙ではありませんか?その理由は後でわかるでしょう。 ROM アレイをクローズアップした画像はこちらです。 マイクロコードビット、ズームイン 明るく水平に走るトレースは、チップの金属層の一部です。黄色っぽい点は、金属層と、その下のポリシリコン層を接続するインターコネクトです。金属層の後ろに見える垂直バーに注意してください。また、インターコネクトの各側にあるポリシリコンには、時折ギャップがあることに注意してください。これらのギャップがトランジスタを形成しており、トランジスタの存在が 1 ビットを示します。これを少し見やすくするために、1 ビットをハイライトします。 これを見て非常に興奮しました。ROM のビットを視覚的に識別できれば、ROM の内容を抽出できるからです。ただ一つの小さな問題があります。アレイには 29,928 ビットがあります。手作業で抽出するのは少し面倒です。 幸いなことに、このタスクにはツールが利用可能です。Travis Goodspeed 氏の MaskRomTool で ROM イメージを読み込みました。 MaskRomTool でビット位置を定義する MaskRomTool を使用すると、ビットの位置を定義する行と列を描画できました。残念ながら、そのビット検出方法はしきい値処理に基づいていたため、ビットと非ビットのコントラストに十分な差がなく、効果的な検出メカニズムになりませんでした。ビットヒストグラムが遠い軸に向かって非常に圧縮されているのがわかります。これはうまくいきませんでした。明るい金属層がなければ、しきい値処理技術はもっとうまく機能したかもしれませんが、InfoSec DJ にそれを除去するように依頼したくはありませんでした。 別の方法が必要でした。 幸いなことに、MaskRomTool を使用して定義したビット位置を JSON 形式でエクスポートできました。このエクスポートされた JSON ファイルを使用して、各ビット位置を中心に正方形のビットマップを抽出し、ファイル名にビットの論理的な列と行番号を付けて保存する Python スクリプトを作成しました。これにより、105MB の ZIP ファイルに、ビットまたは非ビットのいずれかを含む小さな 42x42 ピクセルの PNG ファイルが格納されました。このアイデアは、畳み込みニューラルネットワーク (CNN) をトレーニングして、ビットを 0 または 1 として識別できるようにすることでした。 これがあなたの理解を超えているように聞こえるなら、私はこのプロジェクトの前に CNN のトレーニングに関する経験は全くありませんでしたが、それを 1 日の午後に完了しました。PyTorch のような最新の Python フレームワークは、それを非常に簡単にします。 優れた CNN のチュートリアルはたくさんありますが、その多くは手書き文字認識という古典的な問題に焦点を当てています。しかし、私たちはさらに簡単なタスクを持っています。画像を 0 または 1 の 2 つのバケットに分類するだけです。問題は文字通り「ホットドッグかホットドッグでないか」です。 CNN をトレーニングする前に、トレーニングデータセットが必要です。そこで、Python/tkinter スクリプトを素早く作成し、目の前でビットを 0 または 1 のバケットに素早く分類できるようにしました。 素早く簡単な分類ツール ここに表示されているのは「1」ビットです。金属層の後ろのトランジスタで見つけられますか?ボタンは最終的には不要になりました。キーボードの 1 または 0 を押すだけでビットを分類できます。理論的には、これを 29,928 回実行すれば、数時間で作業は完了します。CNN トレーニングがうまくいかなかった場合のバックアップ方法として、当初はこの方法を意図していました。数人の友人がボランティアで協力してくれることになり、「ビット投票者」が生成する JSON ログをマージして、コンセンサスによる分散作業をサポートできます。幸いなことに、これは必要ありませんでした。 最終的に、この方法で 1,000 ビット強を手動で分類しました。それらを 2 つのディレクトリにソートした後、ソートされた画像をインプットとして CNN モデルのトレーニングを試みることができます。 ここでは CNN の書き方については詳しく説明しません。興味のある方は GitHub でソースをご覧ください。私は優れた PyTorch ライブラリを使用しました。これにより、プロセス全体が想像していたよりもはるかに簡単になりました。 これはトレーニング実行の外観です。 [Epoch 01] train: loss=0.6945 acc=0.7273 f1=0.0164 | val: loss=0.6924 acc=0.7876 f1=0.0000 val precision=0.0000 recall=0.0000 cm=[[178, 0], [48, 0]] [Epoch 02] train: loss=0.6860 acc=0.7151 f1=0.3826 | val: loss=0.6257 acc=0.7965 f1=0.0729 val precision=0.5000 recall=0.0394 cm=[[178, 0], [46, 2]] [Epoch 03] train: loss=0.3751 acc=0.8914 f1=0.7213 | val: loss=0.3900 acc=0.7655 f1=0.6327 val precision=0.4661 recall=1.0000 cm=[[125, 53], [0, 48]] [Epoch 04] train: loss=0.1159 acc=0.9523 f1=0.9139 | val: loss=0.0495 acc=0.9912 f1=0.9773 val precision=0.9773 recall=0.9773 cm=[[177, 1], [1, 47]] [Epoch 05] train: loss=0.0251 acc=0.9945 f1=0.9888 | val: loss=0.0460 acc=0.9867 f1=0.9744 val precision=0.9514 recall=1.0000 cm=[[175, 3], [0, 48]] [Epoch 06] train: loss=0.0319 acc=0.9933 f1=0.9802 | val: loss=0.0438 acc=0.9823 f1=0.9659 val precision=0.9350 recall=1.0000 cm=[[174, 4], [0, 48]] [Epoch 07] train: loss=0.0185 acc=0.9945 f1=0.9212 | val: loss=0.0274 acc=0.9956 f1=0.9891 val precision=0.9792 recall=1.0000 cm=[[177, 1], [0, 48]] [Epoch 08] train: loss=0.0141 acc=0.9956 f1=0.9913 | val: loss=0.0271 acc=0.9956 f1=0.9891 val precision=0.9792 recall=1.0000 cm=[[177, 1], [0, 48]] [Epoch 09] train: loss=0.0101 acc=0.9978 f1=0.9940 | val: loss=0.0447 acc=0.9867 f1=0.9735 val precision=0.9488 recall=1.0000 cm=[[175, 3], [0, 48]] [Epoch 10] train: loss=0.0110 acc=0.9967 f1=0.9907 | val: loss=0.0437 acc=0.9912 f1=0.9773 val precision=0.9773 recall=0.9773 cm=[[177, 1], [1, 47]] Early stopping: no val F1 improvement >= 0.0 for 3 epoch(s). Best val F1: 0.9891 CUDA 対応 GPU をお持ちであれば、トレーニングは非常に迅速です。これはわずか数分しかかかりませんでした。 目標は精度を最大化することですが、1.0 に到達することが不可能ではないかもしれませんし、望ましくないかもしれません (過学習というものがあります)。長期間続けると状況が悪化することもあるため、着実な改善が見られない場合はトレーニングを終了します。トレーニングの出力はニューラルネットワークモデルです。その後、このモデルを使用して、データセット全体で推論を実行できます。推論とは、トレーニングしたモデルを実際に機能させるために適用するという、おしゃれな言葉です。画像が 0 ビットか 1 ビットか予測します。 先に進む前に、論争を避けるための簡単な注意点です。CNN はコンピュータサイエンスの観点からは広義の AI の範囲に含まれますが、ここでは大規模言語モデル (LLM) を指すことが多い、現代的で論争のある意味での「AI」は使用していません。推論パスを実行すると、各ピクセルに対して信頼度スコアが得られます。この信頼度スコアを使用して、モデルがあまり自信を持っていないビットを、特定のしきい値 (ここでは 99% 未満を使用) の下でマークすることができます。これは、ビット分類 CNN の最初の実行結果で、曖昧なビットは赤で色付けされています。 ビット分類 CNN の最初の出力 私はすべての...