pico6502 テクニカルガイド

English

注記: pico6502 プロジェクトは初期開発段階にあります。ハードウェア、PIO バスインターフェース、メモリモデル、ビルドシステムは完全に実装されて動作しています。マシンペルソナドライバーは初期段階にあります。このガイドは現時点のテクニカルアーキテクチャを説明します。

概要

pico6502 のテクニカルアーキテクチャは、CPU バスインターフェースを除くすべての点で picoZ80 と同一です。同じ RP2350B デュアルコアプロセッサー、PSRAM メモリモデル、フラッシュレイアウト、ESP32 コプロセッサー、ドライバーフレームワークを両製品で共有しています。このガイドは 6502 固有の違いに焦点を当て、完全に共通するトピックについては picoZ80 テクニカルガイドを参照します。

ハードウェアアーキテクチャ

ブロック図

┌─────────────────────────────────────────────────────────────────────────┐
│                            pico6502 Board (v2.2)                        │
│                                                                         │
│  ┌───────────────┐   PIO 0: A0–A15, D0–D7      ┌───────────────────┐   │
│  │               │◄──────────────────────────►│  DIP-40 Interface │   │
│  │   RP2350B     │   PIO 1: cycle/ctrl/irq     │   (6502 socket)   │   │
│  │  (300 MHz)    │◄──────────────────────────►│  A0–A15, D0–D7   │   │
│  │               │   PIO 2: PHI1/PHI2 clock ──►│  PHI0/RNW/SYNC   │   │
│  │  Core 0       │                             │  IRQ/NMI/RDY/SO  │   │
│  │  (USB/IO/ESP) │                             └───────────────────┘   │
│  │               │◄──QSPI──►[ 8MB PSRAM ]                             │
│  │  Core 1       │◄──SPI───►[ 16MB Flash ]                             │
│  │  (6502 loop)  │                                                     │
│  │               │◄──FSPI──►┌───────────┐                              │
│  │               │◄──UART──►│   ESP32   │◄──SPI──►[ SD Card ]         │
│  └───────────────┘          │  (WiFi)   │──────────[ Web Server ]     │
│                             └───────────┘                              │
│  [ USB Hub ]──USB──►[ RP2350 USB Bridge ]                             │
└─────────────────────────────────────────────────────────────────────────┘

主要コンポーネント

コンポーネント 部品 仕様
メインプロセッサー RP2350B デュアル Cortex-M33、最大 300 MHz、512KB SRAM、48 GPIO
PSRAM SPI PSRAM 8MB、QSPI インターフェース、最大 133 MHz
フラッシュ SPI NOR Flash 16MB、XIP(実行時実行)
コプロセッサー ESP32-S3 WiFi、SD カード、ウェブサーバー、RP2350 への 460.8kbaud UART
SD カード FAT32 ROM イメージ、ディスクイメージ、config.json、ウェブファイル
バスインターフェース 抵抗ネットワーク 5V ↔ 3.3V レベル変換用直列抵抗
電源 TLV62590BV 同期バック、5V(VCC ピン)→ 3.3V、全基板電源
USB オンボードハブ ファームウェア書き込み用 RP2350 USB マスストレージブリッジ

GPIO 割り当て

以下の GPIO 割り当ては pico6502 v2.2 基板の典型的なレイアウトを示しています。KiCad 回路図(kicad/PICO6502/PICO6502_Schematic.pdf)が権威ある情報源です。
GPIO 信号 方向 備考
0–15 A0–A15 出力 6502 アドレスバス — PIO 0 m6502_addr が駆動
16–23 D0–D7 双方向 6502 データバス — PIO 0 m6502_data が駆動/サンプリング
24 PHI0 入力 PIO 2 への外部クロック入力
25 PHI1 出力 フェーズ 1 クロック出力 — PIO 2 が生成
26 PHI2 出力 フェーズ 2 クロック出力 — PIO 2 が生成
27 RNW 入力 リード/ノットライト — PIO 1 がサンプリング
28 SYNC 出力 オペコードフェッチインジケーター — PIO 1 が駆動
29 IRQ 入力 マスク可能割り込み(アクティブロウ)— PIO 1 が監視
30 NMI 入力 ノンマスカブル割り込み(アクティブロウ)— PIO 1 が監視
31 RDY 入力 レディ信号 — PIO 1 がサンプリング
32 SO 入力 セットオーバーフロー — PIO 1 が監視
33 RESET 双方向 システムリセット(アクティブロウ)
34–39 Flash SPI NOR フラッシュ(XIP)
40–45 PSRAM QSPI PSRAM
46–47 ESP32 FSPI ESP32 への SCLK、CS
48–49 ESP32 UART ESP32 への TX/RX 460.8kbaud

ファームウェアアーキテクチャ

フラッシュメモリレイアウト

picoZ80 のレイアウトと同一:
パーティション アドレス範囲 サイズ 内容
ブートローダー 0x10000000–0x1001FFFF 128KB USB ブリッジ、ファームウェア更新、パーティションセレクター
アプリスロット 1 0x10020000–0x1051FFFF 5MB メイン 6502 ファームウェア(パーティション 1)
アプリスロット 2 0x10520000–0x10A1FFFF 5MB メイン 6502 ファームウェア(パーティション 2)
アプリ設定 1 0x10A20000–0x10C9FFFF 2.5MB ROM イメージ + 最小化された設定 JSON(スロット 1)
アプリ設定 2 0x10CA0000–0x10F1FFFF 2.5MB ROM イメージ + 最小化された設定 JSON(スロット 2)
汎用設定 0x10F20000–0x10FFEFFF 892KB コア設定、スクラッチスペース
パーティションテーブル 0x10FFF000–0x11000000 4KB アクティブスロット、チェックサム、メタデータ

デュアルコア設計

コア 担当
コア 0 USB マスストレージブリッジ;ファームウェアパーティション管理;ESP32 へのファイル I/O リレー;ESP32 UART コマンドディスパッチ;コア間キューサービス
コア 1 6502 バスエミュレーションホットループ — すべてのバスサイクルで PIO FIFO をサービス、メモリマップに対してアドレスを解決、PSRAM / PHYSICAL / FUNC ハンドラーにディスパッチ、ドライバーポールコールバックを呼び出し

PIO バスインターフェース

6502 バスインターフェースは、すべての 3 つの RP2350 PIO ブロックにまたがる M6502.pio に実装されています。Z80 インターフェースとの主な違いは、6502 の二相非重複クロックスキームです。PHI0 は外部クロック入力で、PIO 2 がそこから PHI1 と PHI2 を生成します。これにより、コア 1 のスケジューリングに依存せず正確な 6502 バスタイミングが保証されます。

PIO プログラム

PIO ブロック プログラム ステートマシン 機能
PIO 0 m6502_addr SM 0 16 ビットアドレス A0–A15 を出力;IRQ 0(サイクル開始)を通知
PIO 0 m6502_data SM 1 D0–D7 を駆動またはサンプリング;IRQ 1(データフェーズ)を通知;RNW 経由でトライステート制御
PIO 1 m6502_cycle SM 0 トップレベルバスサイクルシーケンサー;IRQ 7 = 実行ループ終了
PIO 1 m6502_fetch SM 1 オペコードフェッチサイクル(SYNC アサート、PHI2 ハイ、RNW=1)
PIO 1 m6502_read SM 1 メモリリードサイクル
PIO 1 m6502_write SM 2 メモリライトサイクル
PIO 1 m6502_irq SM 2 IRQ ピンを監視;アサート時に PIO IRQ 5 を通知
PIO 1 m6502_nmi SM 3 NMI ピンを監視;アサート時に PIO IRQ 4 を通知
PIO 1 m6502_so SM 3 SO(セットオーバーフロー)ピンを監視;PIO IRQ 6 を通知
PIO 2 m6502_clock_6502 SM 0 外部 PHI0 入力から PHI1/PHI2 二相クロックを生成

IRQ 信号の規約

PIO IRQ フラグ 信号 トリガー元 消費元
IRQ 0 サイクル開始 m6502_addr — PHI1 でアドレス有効 コア 1 ディスパッチループ
IRQ 1 データフェーズ m6502_data — データバスアクティブ コア 1 ディスパッチループ
IRQ 4 NMI m6502_nmi — NMI ピンロウ コア 1 NMI ハンドラー
IRQ 5 IRQ m6502_irq — IRQ ピンロウ コア 1 IRQ ハンドラー
IRQ 6 SO m6502_so — SO ピンハイ コア 1 SO ハンドラー
IRQ 7 ループ終了 ソフトウェアリクエスト m6502_cycle — 実行ループ終了

PHI1/PHI2 クロック生成

6502 は二つの非重複クロックフェーズを必要とします。PIO 2 は専用の GPIO で外部 PHI0 入力を受け取り、正確な非重複タイミングで PHI1 と PHI2 を生成する m6502_clock_6502 プログラムを実行します。クロック生成専用に PIO ブロック全体を割り当てることで、6502 バスタイミングがコア 1 のアクティビティや FIFO のストールに影響されないことが保証されます。

ウェイトステートと RDY

6502 の RDY 信号はウェイトステートの挿入に使用できます。リードサイクル中に RDY をローにホールドすることで、RDY がハイになるまでプロセッサーが停止します。pico6502 はコア 1 からプログラムで RDY をアサートし、低速な仮想デバイス(例:フロッピーディスクエミュレーション)にアクセスする際にウェイトステートを挿入できます。メモリマップ JSON エントリーの tcycwait パラメーターは、特定のメモリ領域に挿入するウェイトステートの数を指定します。

PIO アーキテクチャ — 6502 バスサイクルの再現方法

RP2350 のプログラマブル I/O(PIO)サブシステムは、3 つの PIO ブロックにまたがる 10 個のステートマシンを使用して、サイクル精度の 6502 バスタイミングを再現します。picoZ80 PIO との根本的な違いは 2 点です:6502 は単一クロックではなく二相非オーバーラップクロック方式(PHI1/PHI2)を使用すること、そして別々の /RD/WR 信号の代わりに単一の R/W̄(リード/ノットライト)信号を使用することです。

二相クロック生成
6502 には非オーバーラップの 2 つのクロック — PHI1 と PHI2 — が必要です。外部 PHI0 信号がリファレンスを提供し、PIO 2 がそこから PHI1 と PHI2 を生成します。m6502_clock_6502 ステートマシン(PIO 2 SM 0)はこれを以下のように実装します:
PHI0(入力):  ──┐        ┌──┐        ┌──
                 │        │  │        │
                 └────────┘  └────────┘

PHI1(出力):    ┌──────┐              ┌──────┐
                  │      │              │      │
               ───┘      └──────────────┘      └───

PHI2(出力): ───┐              ┌──────┐              ┌──
                  │              │      │              │
                  └──────────────┘      └──────────────┘
                  ↑              ↑      ↑
                  │              │      │
            PHI0 立ち下がり  PHI0 立ち上がり  PHI0 立ち下がり
            → 短いギャップ   → 短いギャップ   → 短いギャップ
            → PHI1 立ち上がり → PHI1 立ち下がり
                             → PHI2 立ち上がり
SM は jmp pin で PHI0 のエッジを検出し、set pins で正しい非オーバーラップギャップを持って PHI1 と PHI2 の両方を駆動します。最初の set pins 命令の [1] 遅延アノテーションが非オーバーラップ期間を作成します — 遷移中に両方のクロックが一時的にローになります。クロック生成に PIO ブロック全体を専用にすることで、6502 のバスタイミングが FIFO ストールやコア 1 のレイテンシーの影響を受けないことが保証されます。

out exec, 32 メカニズム
picoZ80 と同様に、pico6502 も out exec による動的命令インジェクションを使用しますが、重要な違いがあります:6502 のサイクル SM は Z80 の out exec, 16(16 ビット命令)ではなく out exec, 32(32 ビット命令)を使用します。これにより、サイドセットビット、遅延値、拡張オペランドを含む完全な 32 ビット PIO 命令エンコーディングが単一の FIFO プッシュで可能になります。
m6502_cycle SM(PIO 1 SM 0)がすべてのバスサイクルをオーケストレートします:
// m6502_cycle SM プログラム(PIO 1 SM 0):
//
// start_cycle:
//     wait 0 gpio CLK2      ; PHI2 立ち下がりエッジに同期(新サイクル開始)
//     irq set 0             ; 「新しいサイクル準備完了」を通知
//     wait 0 irq 0          ; C コードがアドレスをロードして IRQ 0 をクリアするまで待機
// cycle_exec:
//     out exec, 32           ; FIFO から 32 ビット命令を取得し実行
//     jmp cycle_exec         ; 繰り返し
// cycle_end:
//     irq set 7              ; 実行ループ終了フラグ
// cycle_exec2:
//     out exec, 32           ; インジェクトされた命令の実行を継続
//     jmp cycle_exec2        ; JMP start_cycle が実行されるまでループ
C コードは各サイクルタイプ(フェッチ、リード、ライト)の 32 ビット命令シーケンスをプリコンパイルし、FIFO にプッシュします。サイクル SM は各命令を順に取得して実行し、アドレスおよびデータ SM と IRQ フラグを介して連携しながら SYNCR/W̄ 信号を制御します。

6502 バスサイクルタイプ
6502 には 3 つのバスサイクルタイプがあり、すべて R/W̄SYNC の状態で制御されます:
オペコードフェッチ(m6502_fetch):
PHI1:      ┌──────┐              ┌──
           │      │              │
        ───┘      └──────────────┘
PHI2:   ───┐              ┌──────┐
           │              │      │
           └──────────────┘      └───
A0–A15: ══╤═══ PC アドレス ═════════╗   (PHI1 立ち上がりで有効)
R/W̄:    ──┤── ハイ(リード)────────╢
SYNC:   ──┤── ハイ(フェッチ)──────╢   (SYNC ハイ = オペコードフェッチ)
D0–D7:  ══════════════════╤════════╗   (PHI2 立ち下がりでサンプリング)
                       オペコード


メモリリード(m6502_read):
           フェッチと同じタイミング、ただし SYNC = ロー。


メモリライト(m6502_write):
PHI1:      ┌──────┐              ┌──
           │      │              │
        ───┘      └──────────────┘
PHI2:   ───┐              ┌──────┐
           │              │      │
           └──────────────┘      └───
A0–A15: ══╤═══ アドレス ════════════╗   (PHI1 立ち上がりで有効)
R/W̄:    ──┤── ロー(ライト)────────╢   (R/W̄ ロー = ライト)
SYNC:   ──┤── ロー ────────────────╢
D0–D7:  ══════════════╤═══ データ ══╗   (PHI2 ハイ中に駆動)
Z80 PIO 実装との主な違い:
  • 単一 R/W̄ 信号 — Z80 の個別 /RD/WR 信号を置き換えます。m6502_fetchm6502_read SM は R/W̄ をハイに設定、m6502_write はローに設定します。
  • SYNC 信号 — 6502 はオペコードフェッチ中に SYNC をアサートして通常のリードと区別します。m6502_fetch SM は SYNC をハイに設定、m6502_readm6502_write はローのままにします。
  • PHI2 ベースのデータサンプリング — データバスは Z80 のように特定の T ステートクロックエッジではなく、PHI2 立ち下がりエッジ(サイクル終了時)でサンプリングされます。m6502_data SM は wait 0 gpio CLK2 でデータキャプチャーのタイミングを計ります。
  • RDY ベースのウェイトステート — Z80 の /WAIT 信号の代わりに、6502 は RDY を使用します。リードサイクル中に RDY がローの場合、プロセッサーが停止します。フェッチとリード SM は各 PHI2 立ち上がりエッジ後に jmp pin で RDY を確認します。
  • リフレッシュサイクルなし — 6502 には DRAM リフレッシュサイクルがないため、フェッチサイクルがよりシンプルです(T3–T4 リフレッシュフェーズなし)。
  • I/O 専用サイクルなし — 6502 には IN/OUT 命令がありません。すべてのペリフェラルアクセスはメモリマップドリードとライトを介して行われます。

信号監視ステートマシン
3 つの専用 SM が 6502 の非同期入力信号を監視します:
  • m6502_irq(PIO 1 SM 2)— /IRQ ピンを監視。/IRQ がローになると PIO IRQ 5 をセットし、ピンがハイに戻るまで保持した後フラグをクリアします。コア 1 は IRQ 5 を確認して割り込みベクターフェッチシーケンスのインジェクトが必要かを判断します。
  • m6502_nmi(PIO 1 SM 3)— /NMI を監視し PIO IRQ 4 をセット/クリア。コア 1 の NMI ハンドラーは $FFFA/$FFFB を通じてベクタリングする適切なバスサイクルシーケンスをプッシュします。
  • m6502_so(PIO 1 SM 3)— SO(セットオーバーフロー)ピンを監視し PIO IRQ 6 をセット/クリア。一部の 6502 システム(特に Commodore ディスクドライブ)がデータレディイベントの通知に使用します。
3 つの SM すべてが同じパターンを使用します:jmp pin でピンのアクティブ化を検出、irq set でコア 1 に通知、その後ループ内の jmp pin でピンの復帰を検出し、irq clear で完了。これにより、非同期エッジイベントが同期 IRQ フラグに変換され、コア 1 がホットループ内で効率的にポーリングできます。

メモリモデル

pico6502 のメモリモデルは picoZ80 のモデルと構造的に同一ですが、重要な違いが一つあります。6502 には独立した I/O アドレス空間がありませんt_6502PSRAMioPtr[] 配列はなく、iomap の JSON セクションもありません。すべてのペリフェラルレジスターは FUNC タイプのブロックを使用して 64KB メモリアドレス空間にマップされます。

ティア 1 — RP2350 SRAM(高速ディスパッチテーブル)

_membankPtr[] に 128 × 32 ビットエントリー、64KB アドレス空間の 512 バイトブロックごとに 1 エントリー。各エントリーはブロックタイプ、PSRAM バンク番号、ブロックベースアドレスを 1 つの 32 ビットワードにエンコードし、すべてのバスサイクルで O(1) ディスパッチを実現します:
// 32ビット membankPtr エンコード
// ビット 31–24: MEMBANK_TYPE_xxx 定数
// ビット 23–16: PSRAM バンク番号(0–63)
// ビット 15–0:  ブロックベースアドレス >> 9(16ビットアドレスの上位 7 ビット)
#define MEMBANK_ENCODE(type, bank, base) (((type) << 24) | ((bank) << 16) | ((base) >> 9))

ティア 2 — PSRAM(8MB)

8MB の PSRAM は RAM/ROM 領域と関数ポインターテーブルの間で分割されます:
typedef struct {
    uint8_t      RAM[MAX_MEMORY_BANKS * MEMORY_PAGE_SIZE]; // 64バンク × 64KB = 4MB RAM/ROM領域
    MemoryFunc   memPtr[MEMORY_PAGE_SIZE];                  // 64K バイト単位リードリダイレクト(PTR タイプ)
    MemoryFunc   memioPtr[MEMORY_PAGE_SIZE];                // 64K メモリマップハンドラー配列(FUNC タイプ)
    // 注: ioPtr[] なし — 6502 には独立した I/O 空間がない
} t_6502PSRAM;

ティア 3 — フラッシュ(16MB)

16MB のフラッシュにはブートローダー、2 つの 5MB アプリケーションファームウェアスロット、ROM イメージと最小化された JSON の 2 つの設定スロット、汎用設定、パーティションテーブルが格納されます。上記「ファームウェアアーキテクチャ」セクションのフラッシュメモリレイアウト表を参照してください。

メモリブロックタイプ

定数 動作
MEMBANK_TYPE_PHYSICAL 0 実際のホストハードウェアへのパススルー — RP2350 がバスを解放
MEMBANK_TYPE_PHYSICAL_VRAM 1 設定可能なウェイトステートを持つホストビデオ RAM
MEMBANK_TYPE_RAM 2 読み書き — PSRAM バンクが裏付け
MEMBANK_TYPE_ROM 3 読み取り専用 — PSRAM バンクが裏付け;書き込みは無視
MEMBANK_TYPE_VRAM 4 ウェイトステート付き PSRAM ビデオ RAM ミラー
MEMBANK_TYPE_FUNC 5 仮想デバイス — すべてのアクセスで memioPtr[addr] ハンドラーを呼び出し
MEMBANK_TYPE_PTR 6 バイト単位リダイレクト — リード時に memPtr[addr] ハンドラーを使用

設定リファレンス

pico6502 は picoZ80 と同じ JSON 設定メカニズムを使用します。トップレベルキーは "esp32""rp2350" です。CPU 固有のセクションはキー "6502""z80" ではなく)を使用します。6502 には I/O 空間がないため "io" 配列はなく、"memory" 配列のみです。

esp32.core

キー タイプ 説明
device 文字列 CPU デバイスタイプ。pico6502 では "6502" でなければなりません。
mode 整数 デフォルト起動モード:0 = クライアント(ステーション)、1 = アクセスポイント。

esp32.wifi

キー タイプ 説明
override 0/1 1 = このブロックのすべての WiFi 設定を適用;0 = NVS の設定を使用。
wifimode 文字列 "ap" または "client"
ssid 文字列 作成する(AP)または参加する(クライアント)ネットワーク名。
password 文字列 WiFi パスフレーズ。
ip 文字列 固定 IP アドレス。
netmask 文字列 サブネットマスク。
gateway 文字列 デフォルトゲートウェイ。
dhcp 0/1 クライアントモードのみ。1 = DHCP、0 = 固定 IP。
webfs 文字列 SD カード上のウェブファイルシステムのルートディレクトリ(デフォルト "webfs")。
persist 0/1 1 = 起動のたびに解決された設定を NVS に書き戻す。

rp2350.core

キー タイプ 説明
cpufreq 整数 RP2350 システムクロック(Hz)(例:300000000)。
psramfreq 整数 PSRAM SPI クロック(Hz)(例:133000000)。
voltage 浮動小数点 RP2350 コア電圧(例:1.10)。

rp2350.6502.memory[ ]

6502 メモリマップを定義します。すべてのペリフェラルは FUNC タイプのエントリーとしてここに記述する必要があります — 独立した I/O マップはありません。
キー タイプ 説明
enable 0/1 このエントリーがアクティブかどうか。
addr 16 進文字列 6502 アドレス空間内の開始アドレス(例:"0xE000")。
size 16 進文字列 領域サイズ(バイト)(例:"0x2000")。
type 文字列 PHYSICALPHYSICAL_VRAMRAMROMFUNC、または PTR
bank 整数 RAM/ROM タイプの PSRAM バンク番号(0–63)。
tcycwait 整数 この領域に挿入するウェイトステート(RDY ストレッチング)。
task 文字列 FUNC タイプのブロック用の名前付きタスク/ドライバーハンドラー。
file 文字列 起動時に読み込む ROM イメージの SD カードパス(ROM タイプ)。

rp2350.6502.drivers[ ]

6502 のドライバーエントリーは Z80 のものより単純です。各エントリーは名前付きドライバー(ファームウェアの virtualFuncMap[] テーブルと照合)を有効化し、オプションで起動時に ROM イメージを PSRAM に読み込みます。
キー タイプ 説明
enable 0/1 このドライバーエントリーがアクティブかどうか。
name 文字列 ドライバー名 — virtualFuncMap[] と大文字小文字を区別せずに照合。
rom[] 配列 起動時に読み込む ROM イメージ。各エントリー:enablefileloadaddr[]

rom[] エントリー:

キー タイプ 説明
enable 0/1 この ROM イメージを読み込むかどうか。
file 文字列 ROM バイナリへの SD カードパス。
loadaddr[] 配列 1 つ以上のロードアドレス記述子:enablepositionaddrbanksize

仮想デバイスフレームワーク

仮想デバイスフレームワークは picoZ80 テクニカルガイドで説明されている picoZ80 のフレームワークと構造的に同一です。主な違いは、すべての仮想デバイスが memioPtr[] に登録されることです — 6502 には ioPtr[] に相当するものがありません。

ハンドラーシグネチャー

// メモリ/ペリフェラルハンドラー — memioPtr[addr] にインストール
// MEMBANK_TYPE_FUNC ブロックへのすべてのアクセスで呼び出される
typedef uint8_t (*MemoryFunc)(M6502CPU *cpu, bool read, uint16_t addr, uint8_t data);

// ドライバー初期化関数 — virtualFuncMap[] に登録
// 2 回呼び出される:pass=0(検証)、pass=1(設定)
typedef int (*VirtualFunc)(M6502CPU *cpu, t_drvConfig *drvConfig, int pass);

ペリフェラルドライバーの作成

pico6502 用の仮想ペリフェラルを追加するには:
  1. MemoryFunc シグネチャーを持つハンドラー関数を作成します。ハンドラーは 6502 リードサイクル(RNW=1)に対して read=true、ライトサイクル(RNW=0)に対して read=false を受け取ります。
  2. VirtualFunc シグネチャーを持つ初期化関数を作成します。設定パス(pass=1)では、ペリフェラルが占有する各アドレスの cpu->_6502PSRAM->memioPtr[addr] にハンドラーをインストールします。
  3. M6502CPU.cvirtualFuncMap[] テーブルにドライバー名と初期化関数を登録します。
  4. config.jsonmemory 配列にアドレス範囲の FUNC タイプエントリーを追加します。
  5. 一致する "name" フィールドを持つドライバーエントリーを config.json に追加します。
VIA6522 ペリフェラル実装を含む完全な例については pico6502 デベロッパーズガイドを参照してください。

ESP32 コプロセッサー

ESP32 コプロセッサーは picoZ80 の ESP32 と機能および実装において同一です — SD カードインターフェース、ウェブサーバー構造、RP2350–ESP32 コマンドプロトコルの完全な説明については picoZ80 テクニカルガイド — ESP32 コプロセッサーを参照してください。

SD カード

SD カードは SPI 経由で ESP32 が排他的に管理します。RP2350 はコア間キューにメッセージを投稿してファイルの読み書きをリクエストし、コア 0 がこれらのリクエストを UART 経由で ESP32 に中継して結果を返します。pico6502 の SD カードディレクトリ構造は picoZ80 と同一です:ウェブファイル用 webfs/、ROM イメージ用 ROM/、ルートに config.json

ウェブサーバー

同じ 7 ページの Bootstrap 4 ウェブサーバーが ESP32 上で動作します。ウェブインターフェースは config.jsonesp32.core.device フィールドから接続されているデバイスタイプを自動検出し、CSS テーマとラベルを調整します(p6502.css スタイルシートが 6502 固有のカラースキームを適用します)。

コマンドプロトコル

RP2350–ESP32 コマンドプロトコルは picoZ80 と pico6502 の両方で同一です。コマンドは 460.8kbaud UART リンク(バルクデータ転送用の 50MHz FSPI がバックアップ)で交換されます。プロトコルは ESP.c / ESP.h で定義され、両方のファームウェアバリアント間で共有されます。

SWD デバッグ — RP2350

pico6502 の SWD デバッグセットアップは picoZ80 と同一です — ハードウェア接続、カスタム rp2350_tzpu.cfg OpenOCD ターゲット、グローバル GDB 初期化の完全な説明については picoZ80 テクニカルガイド — SWD デバッグを参照してください。picoZ80 との違いは:
  • メインファームウェアの ELF は build/bin/model/BaseM6502/BaseM6502_0x10020000.elf です(BaseZ80 ではありません)。
  • ~/.gdbinitadd-auto-load-safe-path エントリーは BaseM6502 を参照しなければなりません。

OpenOCD セットアップ

sudo cp rp2350_tzpu.cfg /usr/local/share/openocd/scripts/target/
openocd -f interface/cmsis-dap.cfg -f target/rp2350_tzpu.cfg -c "adapter speed 5000"

GDB 設定

set history save on
set history filename ~/.gdb_history
set history size 65536
add-auto-load-safe-path build/bin/model/BaseM6502/.gdbinit:build/bin/model/Bootloader/.gdbinit
# ブートローダー — コア 0
cd build/bin/model/Bootloader
cp ../../../../.gdbinit.bootloader.3333 .gdbinit
gdb-multiarch Bootloader.elf


# ブートローダー — コア 1(別ターミナル)
cd build/bin/model/Bootloader
cp ../../../../.gdbinit.bootloader.3334 .gdbinit
gdb-multiarch Bootloader.elf
# メインファームウェア — コア 0
cd build/bin/model/BaseM6502
cp ../../../../.gdbinit.3333 .gdbinit
gdb-multiarch BaseM6502_0x10020000.elf


# メインファームウェア — コア 1(別ターミナル)
cd build/bin/model/BaseM6502
cp ../../../../.gdbinit.3334 .gdbinit
gdb-multiarch BaseM6502_0x10020000.elf

ESP32 — USB デバッグ

picoZ80 と同一 — USB を ESP32 USB ポートに接続し、ESP32-S3 内蔵の USB-JTAG インターフェースを使用します(外部プローブ不要)。
openocd -f board/esp32s3-builtin.cfg

 xtensa-esp32s3-elf-gdb esp32/build/main.elf
(gdb) target extended-remote :3333

ビルドシステム

ビルドシステムは picoZ80 と同一です — RP2350 をターゲットとした Pico SDK 2.x を使用した CMake です。pico6502 は Zeta Z80 エミュレーターライブラリを必要としません。前提条件、ESP-IDF 用 Docker セットアップ、ビルドスクリプトの完全な説明については picoZ80 テクニカルガイド — ビルドシステムを参照してください。pico6502 固有の違いを以下に記します。

ビルドターゲット

ターゲット 出力 説明
BaseM6502 BaseM6502_0x10020000.uf2 メイン 6502 ファームウェア — スロット 1 ロードアドレス
BaseM6502 BaseM6502_0x10520000.uf2 メイン 6502 ファームウェア — スロット 2 ロードアドレス
Bootloader Bootloader.uf2 共有ブートローダー(picoZ80 と同一)
ESP32 main.bin ESP32 ファームウェア(picoZ80 と共有)

ビルドコマンド

# セットアップ(初回のみ)— プロジェクトルートから
export PICO_PATH=/path/to/pico-sdk
./get_and_build_sdk.sh


# 標準リリースビルド
./build_tzpuPico.sh


# デバッグビルド
./build_tzpuPico.sh DEBUG


# ESP32 ファームウェアを含む完全ビルド
./build_tzpuPico.sh ALL


# ESP32 のみ(Docker idf54 エイリアスを使用)
cd projects/tzpuPico/esp32
idf54 build


# USB マスストレージ(BOOTSEL モード)で RP2350 を書き込む
cp build/bin/model/Bootloader/Bootloader.uf2 /media/$USER/RPI-RP2/
cp build/bin/model/BaseM6502/BaseM6502_0x10020000.uf2 /media/$USER/RPI-RP2/


# ESP32 の初回書き込み(esptool を使用)
esptool.py --chip esp32s3 --port /dev/ttyUSB0 --baud 460800 \
  write_flash 0x0   esp32/build/bootloader/bootloader.bin \
             0x8000 esp32/build/partition_table/partition-table.bin \
             0x10000 esp32/build/main.bin

参考サイト

リソース リンク
pico6502 プロジェクトページ /pico6502/
pico6502 ユーザーマニュアル /pico6502-usermanual/
pico6502 デベロッパーズガイド /pico6502-developersguide/
picoZ80 テクニカルガイド /picoz80-technicalguide/
picoZ80 プロジェクトページ /picoz80/
RP2350 データシート datasheets.raspberrypi.com
Pico SDK マルチコア API raspberrypi.github.io/pico-sdk-doxygen
MOS 6502 データシート archive.org
esptool ドキュメント docs.espressif.com
cJSON ライブラリ github.com/DaveGamble/cJSON

無線規制に関する注意事項

本デバイスは 2.4 GHz ISM バンドで送信する ESP32-S3-PICO-1 無線モジュールを搭載しており、世界各国の無線周波数規制(米国の FCC Part 15 Subpart C、欧州連合の無線機器指令 2014/53/EU を含む)において意図的放射器に該当します。
ESP32-S3-PICO-1 モジュール自体は既存の規制認証(FCC、CE など)を取得していますが、そのモジュールレベルの認証は、モジュールを組み込んだ完成品に自動的に適用されるものではありません。事前認証モジュールの免除規定は、個人の趣味愛好家個人使用、実験、または教育目的で少数のデバイスを製作する場合に、個別の機器認可を取得せずに行うことを許可するものです。
重要な制限事項
  • 組み立てられたデバイスは、完成品が独自にテストされ、該当する管轄区域で機器認可(例:FCC ID、認定機関による CE マーキング評価)を取得しない限り、第三者への販売、販売の申し出、贈与、またはその他の方法での配布を行ってはなりません
  • 個人使用のために少数を製作することは、趣味愛好家および実験使用の規定(例:FCC § 15.23)に基づき、デバイスが有害な干渉を引き起こさない限り、一般的に許可されています。
  • 規制要件は国によって異なります。米国外の製作者は、適用される規則について自国の無線周波数当局に確認してください。
製作者の責任
本設計に基づいて製作されたデバイスが、管轄区域内の適用されるすべての無線周波数規制に準拠することは、製作者の単独の責任です。著者は本設計を個人使用、教育、および趣味愛好家向けに提供しており、本設計から製作されたデバイスが商業的配布の規制要件を満たすことについて、いかなる表明も行いません。