Upgrade to Pro — share decks privately, control downloads, hide ads and more …

8bit CPU 2026

Avatar for KOBA789 KOBA789
August 22, 2026

8bit CPU 2026

Kernel/VM探検隊@東京 No19 で発表した内容です。
https://kernelvm.connpass.com/event/395390/

Avatar for KOBA789

KOBA789

August 22, 2026

More Decks by KOBA789

Other Decks in Technology

Transcript

  1. KOBA789 次のKernel/VMつくばを主催してくれる人を探しています ‣ 仕事 ‣ 頑張って作った衛星が海に沈んだり ‣ 懲りずにまた衛星を作っていたり ‣ 趣味

    ‣ 自作DBMSを作ったり(仕事になりつつある) ‣ 年末に24時間でTCP/IPスタックを作ったり ‣ YouTuber活動はもうあんまりやってないかもしれない https://youtube.com/@koba789 https://misskey.io/@koba789
  2. Z80

  3. Z80は、まぁあかん とろくさいアーキが走っとる • 古い • ディスコンになった • 遅い • (RV32エミュレータ上の)Linux

    がブートするのに数時間かかる • 1命令が4〜10サイクル(命令による) • もう3年くらい連続で擦ってて流石にみんな飽きた • これは私の都合
  4. MS213x HDMIキャプチャ専用のIC MS2130とMS2131がある • MS2130 • HDMI Input だけ •

    MS2131 • HDMI Output(Passthrough)や音声入力がある • 1920x1080@60 Lossless YUYV over USB 3.0 • MJPEG みたいなふざけた圧縮ではない
  5. hsdaoh - High Speed Data Acquisition over HDMI HDMIキャプチャをロジアナか何かだと思っている人による先行研究 •

    TDMI to USB 3.0 変換機と見做せる • そうですね • 「A/D 変換したやつを流し込めば SDR ができる」 • そう、ですね? • 「色の変換などを無効化する方法は試行錯誤と観察で見つけた」 • なに言ってんだこいつ https://github.com/steve-m/hsdaoh
  6. Intel MCS-51 (Intel 8051) MCS-51がシリーズ名。8051が製品名 • 大ヒットした 8bit マイコンアーキテクチャ •

    オリジナルの8051は滅んだが、命令セットはコピーされて生き続けている • Cypress の EZ-USB FX2 などにも入ってますね • Zilog Z80: 1976年 • 汎用コンピュータ向け。メモリ空間が素直 • Intel 8051: 1980年 • 組込み向け。ハーバードな感じでメモリ空間がキモい
  7. コード空間 64 KB 0x0000 内部 RAM(IRAM)256 B 0x00 リセットベクタ 外部データ空間

    XDATA 64 KB レジスタバンク 4 同じ番地が 2 つある R0-R7 が 4 組。PSW の RS1:RS0 で選ぶ 0x0003 から 8 バイト間隔で割り込みベクタ INT0 / T0 / INT1 / T1 / シリアル(+ T2 は 8052) 選んでいないバンクはただの RAM 上位 128 は IRAM と SFR で 0x20 ビットアドレス 128 bit ビット番地 0x00-0x7F(SETB / CLR / JB) MOV A,0x90 → SFR の P1 0x30 0x0000 番地が重なっている。 汎用。直接でも間接でも MOV R0,#0x90 MOV A,@R0 → IRAM 上位 SP のリセット値は 0x07 なので、最初の push は 0x08 = バンク 1 に載る MOVX でしか触れない 直接 → SFR、間接 → IRAM コンパイラの変数もここを取り合う MOVX A,@DPTR 16 bit で 64 KB 全域 SFR は 8 の倍数の番地だけが ビットアドレス可能(0x80-0xFF) 読み書きだけ。ここの命令は実行できない 外付け RAM でも内蔵周辺レジスタでもよい SDCC: __sfr __at(0x90) 命令フェッチと定数表 SFR 0x80-0xFF 読み出せるだけ。書く命令は無い 0x80 MOVC A,@A+DPTR / MOVC A,@A+PC 間接アドレッシングのみ 0x80 MOV A,@R0 / @R1 でしか届かない 内蔵 ROM か外付け ROM。外付けなら EA ピンで選び、PSEN で読む データ空間とは物理的に別(ハーバード) 直接で 0x80-0xFF と書くと SFR になる 8051 にはここが無い スタックはここまで伸ばせる SDCC: __code 0xFF 0xFFFF SDCC: __data / __idata 同じ番地 0x80-0xFF 8052 以降で追加された 128 B。元の (直接のみ) P0, SP, DPL/DPH, PCON TCON, TMOD, TL0/TH0, TL1/TH1 0x90 P1, SCON, SBUF 0xA0 P2, IE 0xB0 P3, IP 0xC0 機種ごとの周辺がここに生える 0xD0 PSW 0xE0 ACC(アキュムレータ) 0xF0 PDATA 256 B ̶ MOVX A,@R0 / @R1 が届く範囲 下位 8 bit は Ri、上位 8 bit は P2 が出す → ページは P2 を書けば動かせる 64 KB より広い記憶を載せる石は、この上に 窓とページレジスタを自前で足す SDCC: __xdata / __pdata B 0xFFFF どの空間に当たるかは命令が決める MOVC A,@A+DPTR / @A+PC → コード空間 64 KB MOVX A,@DPTR → XDATA 64 KB MOV A,direct (0x00-0x7F) → IRAM の下位 128 MOVX A,@R0 / @R1 → XDATA の 256 B ページ(上位は P2) MOV A,direct (0x80-0xFF) → SFR SETB / CLR / JB bit → ビット空間(IRAM 0x20-0x2F と SFR) MOV A,@R0 / @R1 → IRAM 256 B 全域 PUSH / POP / LCALL → IRAM(SP が指す)
  8. FPGAでNOR Flashをエミュレートする FPGA を NOR フラッシュに見せて、ホストのコードを実機で走らせる 起動時 ̶ マスク ROM

    が 4 回だけ読む経路 MS2131 のブートフラッシュ (W25Q64JV) を外し、iCE40-HX8K に置き換える。ブリックしない・焼き直し十数秒。 起動後 ̶ ファーム自身が読むペイロード ホスト PC (Linux) iCE40-HX8K breakout iCE40HX8K — top_cfg.v SDCC emu/target8051 → emu.bin 約 36 KB / 上限 64,501 B MS2131 (実機) DO (データ) spislave.v MS2131 から見た SPI フラッシュ 03h に 41.7 ns で応答する mkpayload.py ここに FPGA の 4 本を繋ぐ。I/O は 3.3 V /CS · CLK · DI imgsrc.v 先頭 4 KB・末尾 512 B・ ペイロード先頭 4 KB を BRAM に 中間は FIFO で先読み yosys + nextpnr top_cfg.v → ビットストリーム head/tail キャッシュを内蔵 cfgflash.v コンフィグフラッシュへ書く 実フラッシュは必ず外す (/CS が共通で DO が衝突する) FPGA を先にコンフィグさせてから MS2131 を起こす 12.5 MHz Image + DTB → payload.bin deflate / LZMA で圧縮 iceprog (FTDI) W25Q64JV ソケット iceprog コンフィグフラッシュを SCK 30 MHz で読む 1 マスク ROM — 起動時に 03h READ を 4 回 0x000000 2 B マジック 3C C3 の確認 0x000000 0x30 B 48 バイトのヘッダ (code_len を読む) 0x30+code_len 4 B チェックサム 2 本 0x000030 code_len コード本体 受理されればリトライは無い。拒否されると 534d:2130 で出てくる 内部コード SRAM (最大 64,501 B) 8051 はここから実行する。XDATA からは見えず、書き換えもできない uhubctl PPPS ハブのポート電源 自己コンフィグとイメージ読み出し N25Q032 (コンフィグ用 4 MB) 観測 msdbg / screen / ffmpeg 走っている実機を覗く 0x000000 ビットストリーム 約 135 KB 2 ファーム自身の SPI マスタ SFR 0xC7-0xCA。CS はエンジンに無いので GPIO2 を手で振る 同じ線で 0x010000 のペイロードを 4 KB ずつ読む ← make prog-cfg 0x100000 ファーム + ペイロード ← make prog-image 電源を切って入れる (uhubctl) — チップにリセット手段は無く、これが唯一の再起動 USB 3.0 SuperSpeed — UVC 60 fps / CDC-ACM のシェル / EP0 の msdbg。ここが唯一の観測窓 ゲスト DRAM 8 MB 展開しながら書く → RV32 エミュレータのゲスト RAM
  9. USBの挿抜を自動化したい: PPPS I have control. • USB には PPPS(Per-Port Power

    Switching)という規格がある • ホストからの制御で電源が切れる • uhubctl という CLI ツールで制御できる • USB ハブが対応していないとダメ • 対応ハブは少ない • RSH-A10 というハブを買った https://www.amazon.co.jp/dp/B081H153FY
  10. Q1: RAMは足りるのか? Linuxをブートするには最低でも数MBは必要 • メモリ空間は 64KB • これは物理メモリのサイズの上限ではない • 純正ファームにスプラッシュスクリーンのビットマップがあった

    • 64KB には到底おさまらない • どこかにデカいフレームバッファがいる • さらにコードを読む • バンク切り替えで XDATA の先に 8MB の DRAM が見える • 勝ち!
  11. Q3: どれくらいの速さなのか ブートに8時間、lsに20分かかるとデモができない • GPIO をパタパタさせて CPU 速度を計測 • 60MHz

    & 1クロック/命令! • Z80(16MHz, 4〜10クロック/命令)のざっくり10倍くらい速い • 大事なのは RAM のアクセス速度 • DRAM の方が遅いので read ではダミーサイクルが必要 • それでも数十クロックくらい • Z80 の BIG MEMORY などよりはよっぽど速い
  12. SPI NOR フラッシュ 8 MB 使うのは先頭 64 KB 未満(63,522 B)

    実行中も SPI マスタで読み書きできる 現物は FPGA のエミュレータに置換済み コード空間 64 KBマスク ROM が読み込むIRAM 256 B (別スケール) 0x0000 0x00 レジスタバンク 4 内部コード SRAM 0x20 ビットアドレス 0x30 直接・間接とも可 0x80 間接のみ / スタック 起動時にフラッシュから XDATA 64 KB (縦は 4 KB 単位で実寸) 外付けビデオ DRAM 8 MB 表示領域 A(0-4 MB) 0x0000 1920x1080 の UYVY がちょうど 1 画面 既定のゲスト RAM はここ(原点 0) = ゲストのメモリがそのまま映像に出る 読み込まれた 63,470 B RV32 のレジスタファイル 内部 RAM 32 KB C のグローバルとスタック 先頭 0x100 は左の IRAM のエイリアス 0x285000 128 B もここに置く XDATA からは見えない 実行中に書き換える 手段は無い 選ぶ を 先 ポート(GPIO) 0xA8 割り込み許可 IE 58 0 F 0x 7/ SFR 0x80-0xFF (直接のみ) 0x80 0xA0 0xB0 0x000000 0x8000 アパーチャ窓 4 KB ビデオ DRAM の 1 ページがここに現れる 5 F0 x 0 き 行 で ↑ いま窓に見えているページ 0x285 UVC の配信開始でここは上書きされる 表示領域 B(4-8 MB) 0x400000 映像には出ない RAM̲SIZE=0x800000 でゲストに足せる 0x9000 0xBC-0xBF 32 bit タイマ 0xC7-0xCA SPI マスタ 書き込みは無視される 窓 ×2 0xC000 0xC0FF まで 256 B は書き戻せる 用途未特定。以降 0xCFFF まで未実装 未実装(0xFF が返る) フラッシュはこの先 0xD1-0xDE 窓 0 → DWC3 のレジスタ 0xFFFF 未使用 窓 1 → DMA バッファ アドレスを先に置いて 32 bit 0xD000 PLL レジスタ(-0xD1BF) PLL ブロック 3 と映像読み出し PLL 残りは用途未特定。ホストの 0xE000 疎なレジスタ HDMI 入力とアナログ間接ポート 7 個だけ 0xF000 ハードウェアレジスタ 映像 / DMA / EDID RAM / ページレジスタ メールボックスから読めるのは 1 ページ = 4 KB、全 2048 ページ 0x7FFFFF SFR の窓 ×2 の向こう(XDATA ではない別空間) 8051 が直に触れる空間 その外にある記憶 窓と、その行き先 MOVX は窓も内部 RAM も同じ速さ(読み 4 / 書き 5 クロック)。 窓 0 = DWC3 のレジスタ空間 窓 1 = DMA バッファ 64 KB USB 3 デバイスコントローラ(Synopsys の汎用 IP) USB のペイロードとリングがここに載る 0xC100 からレジスタファイル。GSNPSID = 0x5533330B 映像は 0x0000 と 0x3C00、2 本目のリングが 0x7800 XDATA の同じ番地とは無関係(0xC40C は 0xFF) MS2130 の純正ファームならホストから吸える