Sharp MZシリーズエミュレータ v2.0 - 開発者ガイド

Part 1 — はじめに&対象読者

本ガイドは、tranZPUter SW-700 ハードウェアプラットフォーム上で動作する Sharp MZ シリーズ FPGA エミュレータを理解・改変・拡張したい開発者を対象としています。Cyclone IV FPGA に合成される VHDL 設計と MAX7000AE CPLD バスマネージャから、I/O Processor(K64F ARM Cortex-M4)のインターフェースプロトコル、そして単一の FPGA 内で最大8台の Sharp MZ コンピュータを忠実に再現するエミュレーションサブシステムまで、アーキテクチャの全体像をカバーしています。本ガイドを読み終える頃には、新しいエミュレーション対象機種の追加、既存ペリフェラルの拡張、新しいハードウェアサブシステムの統合、あるいは設計上のタイミングや機能的な問題のデバッグができるようになるでしょう。

本ガイドの対象者

背景 得られる知識
FPGA / HDL 開発者 VHDL アーキテクチャ、クロックドメイン、メモリマップ、CONFIG バス、ハードウェアモジュールの追加方法に関する深い理解
組み込み開発者 K64F ARM I/O Processor が IOP インターフェース、チップセレクトプロトコル、割り込みサービスを通じて FPGA と通信する方法
tranZPUter ハードウェアオーナー SW-700 ボードが複数の Sharp MZ コンピュータをエミュレートする仕組みとモード切替方法の全体像
学生 / ホビイスト 実際のビルド、CI/CD、デバッグワークフローを含む、本格的なマルチマシン FPGA エミュレーションプロジェクトのエンドツーエンドの概観

リポジトリ

リポジトリ 内容 URL
tranZPUter FPGA + CPLD VHDL、回路図、PCB、TZFS ソフトウェア git.eaw.app/eaw/tranZPUter
TZFS tranZPUter Filing System(Z80 アセンブリ) git.eaw.app/eaw/TZFS
SharpMZ Sharp MZ エミュレーション共有 VHDL(共通祖先) git.eaw.app/eaw/SharpMZ

エミュレーション対象機種

機種 シリーズ 状態 主な違い
MZ-80K パーソナル 完成 1978年のオリジナルモデル、Z80 @ 2MHz、モノクロ 40x25
MZ-80C パーソナル 完成 MZ-80K の廉価版
MZ-1200 パーソナル 完成 コンパクトデスクトップ、MZ-80A の前身
MZ-80A パーソナル 完成 MZ-80K の強化版、最も人気のあるモデル
MZ-700 パーソナル 完成 カラーディスプレイ、異なるキーボードマトリクス、3.58MHz
MZ-800 パーソナル 部分的 MZ-700 の拡張版、拡張グラフィックスモード、QD ドライブ
MZ-80B ビジネス 完成 ビジネスシリーズ、80桁表示、GRAM、Z80 PIO
MZ-2000 ビジネス 部分的 MZ-80B の強化版、FDD 対応、APSS テープ

関連ドキュメント

ハードウェアアーキテクチャと回路図については tranZPUter SW-700 ページを参照してください。ユーザー向けの操作方法と TZFS コマンドについては TZFS ユーザーマニュアルを参照してください。TZFS ソースコードの解説については TZFS 開発者ガイドを参照してください。MiSTer(Cyclone V)版エミュレータについては Sharp MZ MiSTer 開発者ガイドを参照してください。


Part 2 — ハードウェアプラットフォーム概要

tranZPUter SW-700 v1.3 は、Sharp MZ-700、MZ-80A、または MZ-2000 の Z80 CPU を物理的に置き換えるカスタム PCB です。ホストマシンのメインボード上の Z80 ソケットに装着し、電気的にはオリジナルの CPU として振る舞いながら、内部には FPGA、CPLD、ARM マイクロコントローラ、512KB の SRAM を搭載しています。ボードは複数のモードで動作可能です:透過パススルー(メインボード上のハード Z80 がそのまま実行)、ビデオ拡張(FPGA がアップグレードされた表示出力を提供)、ソフト CPU ホスト(FPGA 内の T80 Z80 または ZPU Evolution が実行)、あるいは完全な Sharp MZ シリーズエミュレータ(emuMZ ビルド)として動作します。

FPGA: Cyclone IV E(CYC1000 モジュール)

FPGA は CYC1000 キャリアモジュールに搭載された Intel(Altera)Cyclone IV E デバイスです。2つのデバイスバリアントがサポートされています:
パラメータ EP4CE115F23I7 EP4CE75F23I7
ロジックエレメント 114,480 75,408
内蔵メモリ 3,981 Kbits 2,745 Kbits
内蔵乗算器 266 (18x18) 200 (18x18)
PLL 4 4
パッケージ FBGA-484 FBGA-484
スピードグレード I7(産業用) I7(産業用)
大容量の EP4CE115 が完全な emuMZ ビルドの主要ターゲットであり、8台のマシンエミュレーション用の ROM/RAM ストレージとロジックに相当なブロック RAM を必要とします。EP4CE75 は coreMZ(ビデオのみ)および coreMZ_SoftCPU ビルドには対応できますが、完全な emuMZ バリアントにはリソースが不足します。

CPLD: MAX7000AE (EPM7512AETC144-10)

CPLD は 512 マクロセルの Altera MAX7000AE です。ホストメインボードの 5V Z80 バスと 3.3V FPGA/SRAM の間に位置し、電圧変換、バスアービトレーション、メモリモードデコード、クロックマルチプレクシングを行います。CPLD はすべての入力で 5V トレラントであるため、外部レベルトランスレータなしで TTL レベルのメインボード信号と直接インターフェースできます。

I/O Processor: ARM Cortex-M4 (K64F)

K64F は 120MHz で動作する Freescale(NXP)Kinetis ARM Cortex-M4 マイクロコントローラです。tranZPUter アーキテクチャでは I/O Processor(IOP)として機能し、FPGA がハードウェアで効率的に処理できないサービスを提供します:SD カードファイルシステムアクセス、テープイメージの読み込み/保存、フロッピーディスクイメージ管理、ユーザーインターフェースメニュー、ホスト設定などです。K64F はチップセレクトライン、6ビットアドレスバス、8ビット双方向データバス、リード/ライトストローブで構成されるパラレルインターフェースを通じて FPGA と通信します。

SRAM: 512KB スタティック RAM

512KB SRAM デバイスは Z80 メモリ空間を提供し、CPLD の TZMM(tranZPUter Memory Mode)レジスタで制御される 64KB ページにマッピングされます。SRAM はハード Z80(CPLD 経由)とソフト T80(FPGA 経由)の両方からアクセス可能で、CPLD がページ選択を制御し、FPGA が emuMZ バリアント用の追加アドレスデコードを行います。

ホストマシンサポート

ホスト ソケット CPLD バリアント 備考
MZ-700 Z80 DIP-40 tranZPUterSW700 主な開発ターゲット
MZ-80A Z80 DIP-40 tzpuSW700_MZ80A 異なるメインボード I/O デコード
MZ-2000 Z80 DIP-40 tzpuSW700_MZ2000 ビジネスシリーズのバスタイミング

Part 3 — アーキテクチャ概要

FPGA 設計は3つのビルドバリアントに分かれており、それぞれが独立したトップレベル VHDL エンティティとして実装されています。3つすべてが VideoController モジュールを共有しており、ソフト CPU コアおよび/または完全な Sharp MZ エミュレーションサブシステムを含むかどうかが異なります。

3つのビルドバリアント

バリアント トップレベルエンティティ 内容 FPGA 使用率 (EP4CE115)
coreMZ coreMZ.vhd VideoController のみ ~15% LE, ~20% BRAM
coreMZ_SoftCPU coreMZ_SoftCPU.vhd VideoController + T80 + ZPU Evolution ~35% LE, ~45% BRAM
coreMZ_emuMZ coreMZ_emuMZ.vhd VideoController + 完全な Sharp MZ エミュレーション ~70% LE, ~85% BRAM

モジュール階層(coreMZ_emuMZ バリアント)

coreMZ (top-level entity, 1783 lines)
├── clkgen          - 128MHz PLL, programmable clock dividers (571 lines)
│                     CKMASTER 8MHz, CKENCPU variable 2-32MHz, CKENHOST, CKSOUND, CKRTC
├── VideoController - Multi-mode video rendering engine (5400 lines)
│                     40/80 col, mono/colour, VGA scaling, OSD overlays, palette
├── mctrl           - Machine control: 91-bit CONFIG bus, register decode, reset (689 lines)
├── T80             - Z80-compatible soft CPU core (T80se wrapper)
├── arbiter         - Round-robin bus arbitration with 1-second watchdog (653 lines)
├── keymatrix       - PS/2 to Sharp MZ keyboard translation (1222 lines)
├── cmt             - Cassette tape interface with APSS support (1806 lines)
├── fdd             - Floppy disk controller, WD1793 emulation (355 lines)
├── iointr          - 8-interrupt FIFO for I/O processor (325 lines)
├── snd             - SN76489 sound + i8253 audio subsystem (369 lines)
├── mz80k_hw        - Personal series hardware controller (1416 lines)
│                     MZ-80K/C/1200/80A/700/800 memory map and I/O
│   ├── i8255       - Programmable Peripheral Interface
│   └── i8254       - Programmable Interval Timer
└── mz80b_hw        - Business series hardware controller (676 lines)
                      MZ-80B/2000/2200/2500 memory map and I/O
    ├── i8255       - PPI (alternate configuration)
    ├── i8254       - PIT (cascade mode)
    └── z8420       - Z80 PIO (Parallel I/O)

データフロー

emuMZ バリアントには2つの独立したデータパスがあります:
  1. エミュレーションパス — T80 ソフト CPU が Sharp MZ ソフトウェアを実行し、アドレスデコードされたチップセレクトを介して ROM、RAM、ビデオ、ペリフェラル、カセットの読み書きを行います。これはクロックイネーブルを使用する CKMASTER クロックで、FPGA クロックドメイン内で完全に動作します。

  2. IOP パス — K64F ARM プロセッサがパラレル IOP インターフェースを通じて FPGA と通信し、設定レジスタ、ROM イメージ、テープデータ、フロッピーディスクイメージ、キーボードマップを送信します。これはエミュレーションクロックに対して非同期です。

両方のパスは共有リソース(CONFIG レジスタ、CMT バッファ、キーボードマトリクス)に競合なくアクセスできます。arbiter モジュールがラウンドロビン方式で競合するリクエストをシリアライズするためです。

Part 4 — FPGA トップレベルエンティティ

トップレベルエンティティ coreMZcoreMZ_emuMZ.vhd で定義)は、すべての FPGA 物理ピン接続を宣言し、すべてのサブモジュールのインスタンス化を含みます。そのアーキテクチャ(rtl)は主に配線作業であり、内部信号を介してサブモジュールポートを接続し、ハード Z80 バス信号とソフト CPU バス信号を切り替えるトライステートバスマルチプレクシングロジックを含みます。

エンティティポート

エンティティポートリストは機能別に信号をグループ化しています:
グループ 信号 方向 用途
クロック CLOCK_50, CTLCLK, SYSCLK, VZ80_CLK in 50MHz ベース、外部オーバーライド、メインボードシステム、Z80 バスクロック
アドレスバス VZ80_ADDR[15:0] inout Z80 アドレス — ソフト CPU 駆動時はアクティブ出力、ハード Z80 アクティブ時は入力
データバス VZ80_DATA[7:0] inout Z80 データ — FPGA リソースからの読み出し時はアクティブ出力、書き込み時は入力
制御 VZ80_MREQn, IORQn, RDn, WRn, M1n inout ソフト CPU からのアクティブ出力またはハード Z80 からの入力
ビデオデコード VIDEO_RDn, VIDEO_WRn in CPLD デコード済みビデオコントローラアクセスストローブ
VGA 出力 VGA_R/G/B[3:0], HSYNC_OUTn, VSYNC_OUTn out チャンネルあたり 4ビット RGB + 同期
コンポジット COLR_OUT, CSYNC_OUTn, CSYNC_OUT out コンポジットビデオ信号
メインボードビデオ入力 V_CSYNC, V_HSYNCn, V_VSYNCn, V_R, V_G, V_B in パススルーまたはブレンド用のオリジナルメインボードビデオ
マルチプレクスピン VWAITn_A21_V_CSYNC 等 inout アドレス拡張、CPU 制御、ビデオ入力間で共有されるピン

トライステートバスマルチプレクシング

アドレスバスとデータバスは、メインボード上のハード Z80 と FPGA 内のソフト T80 で共有されます。トップレベルエンティティには CPU_CFG_DATA レジスタと MODE_EMU フラグで制御されるトライステートドライバが含まれます:
-- When emuMZ is active, the FPGA drives the address and data buses.
-- When the hard Z80 is active, these pins are high-impedance inputs.
VZ80_ADDR <= T80_ADDR           when MODE_EMU = '1' and VZ80_BUSACKni = '0'
             else (others => 'Z');

VZ80_DATA <= T80_DATA_OUT       when MODE_EMU = '1' and CORE_WRn = '0'
             else (others => 'Z');
マルチプレクスピン(VWAITn_A21_V_CSYNC、VZ80_A20_RFSHn_V_HSYNCn 等)は、アクティブモードに応じて3つの役割を果たします。emuMZ モードでは、64KB の Z80 空間を超える FPGA ブロック RAM にアクセスするための上位アドレスビット(A16-A21)を伝送します。ビデオのみモードではメインボードのビデオ同期信号を伝送します。ソフト CPU モードでは CPU ステータス出力(HALT、RFSH)を伝送します。

主要内部信号

信号 ビット幅 用途
CPU_CFG_DATA 8 bits CPU 選択・制御レジスタ (I/O 0x6C)
CPLD_CFG_DATA 8 bits CPLD 設定レジスタ (I/O 0x6E)
MODE_EMU 1 bit フラグ: emuMZ モジュールアクティブ
CORE_ADDR 24 bits アクティブ CPU からの拡張アドレス(64KB を超える FPGA メモリをサポート)
CORE_DATA_OUT/IN 32 bits ZPU およびビデオコントローラのワードアクセス用ワイドデータパス
CONFIG 91 bits mctrl からのマシン設定バス
CLKBUS 7 bits clkgen からのクロック分配バス

Part 5 — クロックアーキテクチャ

clkgen モジュール(571行)は、単一の 50MHz 入力から PLL を使用して 128MHz マスターを生成し、プログラマブル分周チェーンですべてのクロックを生成します。重要な設計原則として、すべての可変周波数クロックは、独立したクロックドメインではなく、マスタークロック上のクロックイネーブルを使用するということです。これによりクロックドメインクロッシングの問題が排除され、タイミング解析が簡素化されます。

クロックバス (CLKBUS)

7ビットの CLKBUS ベクタがすべてのクロックをすべてのモジュールに分配します:
インデックス 名称 機能 代表的な周波数
0 CKMASTER マスター同期クロック 8MHz(128MHz PLL /16 から)
1 CKENHOST ホストマシンクロックイネーブル ~2MHz(オリジナルマシン速度)
2 CKSOUND サウンド生成クロック 3.58MHz または 4MHz
3 CKRTC リアルタイムクロック ~1Hz(分周)
4 CKENCPU CPU クロックイネーブル(可変) 2-32MHz(TURBO 設定による)
5 CKENPERIPH ペリフェラルクロックイネーブル (i8254, i8255) マシン依存
6 CKENFDC フロッピーディスクコントローラクロック 8MHz

クロックイネーブル技法

独立したクロックドメインを生成する代わりに(タイミング収束の問題を引き起こし、明示的なシンクロナイザを必要とする)、設計では単一の CKMASTER クロックとパルス状のクロックイネーブル信号を使用します。例えば T80 CPU は CKMASTER 速度でクロックされますが、CKENCPU が High にパルスしたときのみ状態が遷移します:
-- CPU executes only when CKENCPU pulses
T80se_inst : T80se
    port map (
        CLK_n   => CLKBUS(CKMASTER),
        CLKEN   => CLKBUS(CKENCPU),
        RESET_n => T80_RESETn,
        ...
    );
これにより、可変 CPU 速度をサポートしながら、設計全体を単一のクロックドメインに保ちます。すべてのステートマシン、カウンタ、レジスタは CKMASTER をサンプルし、適切なクロックイネーブルで更新を修飾します。

PLL 設定

PLL は 50MHz の CLOCK_50 入力を受け取り、以下を生成します:
PLL 出力 周波数 用途
c0 128MHz マスター PLL 出力、すべてのイネーブルに分周される
c1 75MHz ビデオピクセルクロック(オプションの高解像度モード)
128MHz 出力はバイナリ分周器のチェーンに供給されます。各分周器は N マスターサイクルごとにシングルサイクルパルスをトグルすることで、ターゲット周波数のクロックイネーブルパルスを生成します。例えば、128MHz から 2MHz の CPU イネーブルを生成するには、分周器が 64 までカウントしてワンサイクルパルスを出力します。

設定可能な周波数

mctrl からの CONFIG バスが、以下のビットフィールドで周波数選択を制御します:
CONFIG ビット パラメータ オプション
[61:59] TURBO CPU 速度: 2MHz, 4MHz, 8MHz, 16MHz, 32MHz
[84:81] CPUSPEED アクティブ CPU 速度(TURBO + マシンタイプから導出)
[86:85] PERSPEED ペリフェラルクロック選択
[88:87] RTCSPEED RTC クロック選択
[90:89] SNDSPEED サウンドクロック選択
ユーザーまたは I/O Processor が CONFIG レジスタを通じて TURBO を変更すると、clkgen は分周値を再計算し、次の分周サイクルで新しい周波数にシームレスに移行します。イネーブルパルスの間隔が変わるだけで、基盤となる CKMASTER クロックは一定のままであるため、グリッチは発生しません。

Part 6 — マシン制御と設定

mctrl モジュール(689行、同ファイル先頭の mctrl_pkg パッケージを含む)は、エミュレーションの中央設定権限です。91ビットの CONFIG バスを管理し、エミュレートされるマシンのあらゆる側面を制御します — どのコンピュータモデルがアクティブか、表示モード、CPU 速度、オーディオソース、テープ速度、フロッピーオプションなどです。リセット配信も管理します。

CONFIG バスビットアサイン

CONFIG バスはハードウェア設定レジスタファイルとして機能するワイドベクタです。各モジュールは自身の機能に関連するビットを読み取ります。完全なマップ(mctrl_pkg より):
ビット 定数 用途
[10:0] CURRENTMACHINE マシンタイプ — ワンホットエンコーディング (MZ80K=0, MZ80C=1, … MZ2500=10)
[11] MZ_KC 集約: マシンは MZ-80K または MZ-80C シリーズ
[12] MZ_A 集約: マシンは MZ-1200 または MZ-80A シリーズ
[13] MZ_B 集約: マシンは MZ-2000/MZ-80B シリーズ
[15] MZ_K 集約: マシンはいずれかのパーソナルシリーズ
[19:16] CURRENTDISPLAY 表示モード: NORMAL(16), NORMAL80(17), COLOUR(18), COLOUR80(19)
[23:20] VGAMODE VGA 出力モード (640x400, 640x480, ピクセルダブリング)
[24] USERROM ユーザー ROM (E800-EFFF) 有効化
[25] FDCROM FDC ROM (F000-FFFF) 有効化
[26] FDDENABLE Floppy Disk Controller 有効化
[27] FDDINTEN FDC 割り込み有効化
[31:28] FDDDISKREADY ドライブごとのディスク装着状態(4ドライブ)
[35:32] FDDPOLARITY ドライブごとのデータ極性
[39:36] FDDWRPROTECT ドライブごとのライトプロテクト
[42:40] RAMINSTALLED 搭載 RAM 設定
[50:43] GRAPHICSOPTION GRAM オプション (GRAMI/II/III, PCG, MZ1R25)
[51] AUDIOSRC オーディオソース: 0=サウンドジェネレータ, 1=テープオーディオ
[55:52] AUDIOVOL 音量(4ビット、16段階)
[57:56] AUDIOMIX オーディオチャンネルミキシング
[58] AUDIOHW オーディオハードウェア選択(ホストまたは FPGA)
[61:59] TURBO CPU 速度選択
[64:62] FASTTAPE テープ読み書き速度倍率
[66:65] BUTTONS 外部ボタン状態(CMT play/record)
[67] PCGRAM PCG モード: ROM(0) または RAM(1)
[68] VRAMWAIT CPU アクセス時のビデオウェイトステート挿入
[69] VRAMDISABLE VRAM 表示出力無効化
[70] GRAMDISABLE GRAM 表示出力無効化
[71] MENUENABLE OSD メニューオーバーレイ有効化
[72] STATUSENABLE OSD ステータスオーバーレイ有効化
[73] BOOT_RESET MZ-80B/2000 Boot IPL Reset 有効化
[74] CMTASCII_IN CMT Sharp ASCII → ASCII 変換(入力)
[75] CMTASCII_OUT CMT ASCII → Sharp ASCII 変換(出力)
[76] CMT_HWMODE ハードウェア CMT ドライブ(1) またはエミュレーション(0)
[80:77] MZ800_SWITCH MZ-800 ハードウェア選択スイッチ
[84:81] CPUSPEED アクティブ CPU 速度(導出値)
[86:85] PERSPEED アクティブペリフェラル速度
[88:87] RTCSPEED アクティブ RTC 速度
[90:89] SNDSPEED アクティブサウンド速度

I/O Processor レジスタインターフェース

mctrl モジュールは I/O Processor に 16 個のアドレス可能なレジスタを提示します。K64F はこれらのレジスタに書き込み(IOP_MCTRL_CSn がアサートされた IOP バス経由)、エミュレーションを設定します。各レジスタは CONFIG ビットのサブセットにマッピングされます:
IOP アドレス レジスタ 影響する CONFIG ビット
0x00 マシン選択 [10:0] CURRENTMACHINE + 集約フラグ
0x01 表示モード [19:16] CURRENTDISPLAY, [23:20] VGAMODE
0x02 CPU/テープ速度 [61:59] TURBO, [64:62] FASTTAPE
0x03 オーディオ設定 [51] AUDIOSRC, [55:52] AUDIOVOL, [57:56] AUDIOMIX
0x04 ROM 有効化 [24] USERROM, [25] FDCROM
0x05 FDD 設定 [26] FDDENABLE, [27] FDDINTEN, [31:28] FDDDISKREADY
0x06 RAM 設定 [42:40] RAMINSTALLED, [50:43] GRAPHICSOPTION
0x07 OSD/その他 [71] MENUENABLE, [72] STATUSENABLE, [67] PCGRAM
0x08 CMT 設定 [74] CMTASCII_IN, [75] CMTASCII_OUT, [76] CMT_HWMODE
0x0F リセット制御 システム全体のリセット生成

リセット管理

mctrl モジュールは3つのソースから統合された MCTRL_RESETn 信号を生成します:
  1. コールドリセット — パワーオンリセットカウンタ(4ビット、~16 CKMASTER サイクル)
  2. ウォームリセット — I/O Processor がリセットレジスタ (0x0F) に書き込み
  3. CPU リセット — CPU_CFG_DATA ビット 7 がセット
すべてのリセットはメタスタビリティ防止のため CKMASTER に同期されます。リセット出力はすべてのサブモジュールにファンアウトします。

Part 7 — CPU 切替メカニズム

tranZPUter SW-700 の特徴的な機能の一つは、実行時に複数の CPU を切り替えられることです。このメカニズムは I/O アドレス 0x6CCPU_CFG_DATA レジスタで制御され、CPLD バスマネージャと FPGA の間で連携されます。

CPU 設定レジスタ (I/O 0x6C)

ビット 機能
[5:0] CPU 選択 000000=Hard Z80, 000001=T80, 000010=ZPU, 000100=emuMZ
[6] クロックイネーブル 1=ソフト CPU クロック動作中, 0=停止
[7] CPU リセット 1=ソフト CPU をリセット状態に保持

利用可能な CPU モード

モード CPU_CFG_DATA[5:0] CPU 説明
Hard Z80 000000 メインボード Z80 ホストマシンのオリジナル CPU、FPGA はビデオのみ提供
Soft T80 000001 FPGA 内 T80 Z80 互換ソフトコア、TZFS および Sharp MZ ソフトウェアを実行
ZPU Evolution 000010 FPGA 内 ZPU 32ビットスタックプロセッサ、zOS を実行
emuMZ 000100 T80 + 完全エミュレーション 完全な Sharp MZ エミュレーション、すべてのペリフェラルが FPGA 内

切替シーケンス

CPU 切替は、TZFS(現在の CPU 上で実行中)が I/O ポート 0x6C に書き込むことで開始されます。シーケンスは以下の通りです:
  1. TZFS がビット 7(リセット)をセットした新しい CPU_CFG_DATA 値を書き込みます — これによりターゲット CPU がリセット状態に保持されます。
  2. CPLD が 0x6C への I/O 書き込みを検出し、内部の CPU モードレジスタを更新します。
  3. ハード Z80 から切替える場合、CPLD がメインボード Z80 に BUSRQn をアサートします。BUSACKn を受信すると、ハード Z80 がバスをトライステートにし、FPGA が制御を引き継ぎます。
  4. ハード Z80 に切替える場合、FPGA がバスドライバをトライステートにし、CPLD が BUSRQn を解除します。
  5. TZFS(または I/O Processor)がビット 7 をクリアし、ターゲット CPU をリセットから解放します。
  6. 新しい CPU がリセットベクタから実行を開始します。

emuMZ モードへの移行

emuMZ モードが選択される(CPU_CFG_DATA[2]=1)と、追加の初期化が行われます:
  1. arbiter モジュールが起動し、T80、キーボードスキャナ、CMT インターフェース、割り込みジェネレータ、サウンドモジュール間のバスアービトレーションを制御します。
  2. mctrl モジュールが選択されたマシンモデルのデフォルト CONFIG をロードします。
  3. I/O Processor が適切なモニター ROM を FPGA ブロック RAM にロードします。
  4. T80 がリセットから解放され、アドレス 0x0000 のモニター ROM から実行を開始します。

Part 8 — ビデオコントローラ

VideoController モジュール(VideoController/VideoController.vhd 内 5400行)は、設計中の最大の単一モジュールです。すべてのエミュレーション対象マシンの完全な表示システムを実装しており、文字レンダリング、カラーアトリビュートオーバーレイ、グラフィックスフレームバッファ合成、VGA アップスケーリング、パレット管理、メニューおよびステータスシステム用の OSD(On-Screen Display)オーバーレイを含みます。

表示モード

モード 解像度 色数 対象機種
モノクロ 40x25 320x200 緑/白 MZ-80K/C/1200/80A
カラー 40x25 320x200 8色 MZ-700/800
モノクロ 80x25 640x200 緑/白 MZ-80A(拡張)
カラー 80x25 640x200 8色 MZ-80B/2000
グラフィックス 320x200 320x200 8色 MZ-700/800 (GRAM)
グラフィックス 640x200 640x200 8色 MZ-80B/2000 (GRAM I/II/III)

レンダリングパイプライン

ビデオレンダリングパイプラインは、各スキャンラインをパイプライン化されたシーケンスで処理します:
  1. タイミング生成: 水平および垂直カウンタが同期、ブランキング、アクティブ表示ウィンドウを生成します。各マシンモデルには CONFIG[10:0] で選択される固有のタイミングパラメータがあります。

  2. 文字フェッチ: 各文字セル(幅8ピクセル)の間に、H/V 位置から VRAM アドレスが計算され、VRAM から文字コードが読み取られ、CGROM(PCG が有効な場合は CGRAM)から対応するグリフ行がフェッチされます。

  3. アトリビュートフェッチ: 同じ文字セルアドレスで ARAM からカラーアトリビュートが読み取られます。アトリビュートバイトは前景色(3ビット)、背景色(3ビット)、およびオプションのブリンク/アンダーラインフラグをエンコードします。

  4. グラフィックスオーバーレイ: GRAM を持つマシン(MZ-80B/2000 またはグラフィックス拡張付き MZ-700/800)の場合、Red、Green、Blue フレームバッファから対応するグラフィックスピクセル行が読み取られます。ブレンドモード(XOR、OR、AND、replace)はグラフィックス制御レジスタで選択されます。

  5. パレットマッピング: 3ビットカラーインデックスがプログラマブルパレット LUT を通じて 12ビット RGB(チャンネルあたり4ビット)に拡張されます。パレットは 4096 色をサポートします。

  6. VGA アップスケーリング: ネイティブ解像度(320x200 または 640x200)が、ピクセルダブリングとラインレプリケーションを使用して設定された VGA 出力モード(640x400、640x480、または 800x600)にスケーリングされます。

  7. OSD 合成: メニューまたはステータスオーバーレイが有効な場合、適切な画面領域で OSD フレームバッファピクセルがエミュレーション表示の上に合成されます。

ビデオメモリマップ(直接 24ビットアドレッシング)

ビデオコントローラが拡張 24ビットアドレスバス(ZPU または I/O Processor が使用)経由でアクセスされる場合、以下のメモリマップが適用されます:
アドレス範囲 サイズ 内容
0x200000-0x20FFFF 64KB I/O レジスタ(パレット、GPU 制御、モード選択)
0x210000-0x21FFFF 64KB Video RAM, attribute RAM, character generator RAM
0x240000-0x243FFF 16KB Red フレームバッファプレーン
0x250000-0x253FFF 16KB Blue フレームバッファプレーン
0x260000-0x263FFF 16KB Green フレームバッファプレーン
0x270000-0x2A1FFF ~200KB OSD フレームバッファ(メニュー + ステータス)
0x320000 8KB ステータスフレームバッファ
0x322000 8KB メニューオーバーレイフレームバッファ
0x324000 1KB ビデオパラメータ配列(32x32 エントリ)
0x324400 4B 現在のビデオモードレジスタ

Z80 アドレス空間ビデオアクセス

Z80 の観点(16ビットアドレッシング)では、ビデオメモリは標準的な Sharp MZ のアドレスにマッピングされます:
機種 VRAM ARAM CGROM/RAM
MZ-80K/C/1200/80A D000-D7FF (2KB) D800-DFFF (2KB) 読み取り専用 CG ROM
MZ-700 D000-D7FF (2KB) D800-DFFF (2KB) ARAM 内のカラーアトリビュート
MZ-80B/2000 D000-DFFF (4KB) - E000-E7FF (GRAM アクセス)

Part 9 — メモリアーキテクチャ

emuMZ ビルドはすべてのエミュレーション対象マシンのメモリに FPGA ブロック RAM のみを使用します。coreMZ および coreMZ_SoftCPU ビルド(CPLD 経由で外部 512KB SRAM を使用)とは異なり、emuMZ バリアントは FPGA 内で自己完結しており、ホストメインボードの RAM にはまったくアクセスしません。

ブロック RAM 割り当て

メモリ サイズ タイプ 初期化ファイル 用途
SYSROM 128KB デュアルポート ROM combined_mrom.mif すべてのマシンモデル用モニター ROM
SYSRAM 64KB デュアルポート RAM combined_mainmemory.mif Z80 メインメモリ
VRAM 4KB デュアルポート RAM テキスト表示バッファ
ARAM 4KB デュアルポート RAM カラーアトリビュート RAM
CGROM 32KB デュアルポート ROM キャラクタジェネレータ ROM(全モデル)
CGRAM 32KB デュアルポート RAM プログラマブルキャラクタ RAM (PCG)
GRAM (Red) 16KB デュアルポート RAM グラフィックスフレームバッファ赤プレーン
GRAM (Green) 16KB デュアルポート RAM グラフィックスフレームバッファ緑プレーン
GRAM (Blue) 16KB デュアルポート RAM グラフィックスフレームバッファ青プレーン
CMT HDR 128B デュアルポート RAM テープファイルヘッダキャッシュ
CMT DATA 64KB デュアルポート RAM テープデータキャッシュ
KEYMAP 2KB デュアルポート RAM キーボードマッピングテーブル

ROM バンキング

SYSROM は単一の 128KB ブロックにすべてのマシンモデルのモニター ROM を格納します。バンク選択は CONFIG バスのマシン選択ビットから駆動される MROM_BANK[5:0] で制御されます。SYSROM の上位アドレスビットがバンクを選択します:
機種 バンクインデックス ROM サイズ SYSROM 内アドレス範囲
MZ-80K 0, 1 4KB + 2KB 0x00000-0x00FFF
MZ-80C 2, 3 4KB + 2KB 0x02000-0x02FFF
MZ-1200 4, 5 4KB + 2KB 0x04000-0x04FFF
MZ-80A 6, 7 4KB + 2KB 0x06000-0x06FFF
MZ-700 8, 9 4KB (1Z-013A) 0x08000-0x08FFF
MZ-800 10, 11 8KB 0x0A000-0x0BFFF
MZ-80B 12, 13 4KB + IPL 0x0C000-0x0CFFF
MZ-2000 14, 15 4KB + IPL 0x0E000-0x0EFFF
ランタイム中のマシンモデル切替はバンクセレクトを変更するだけで、再ロードは不要です。I/O Processor は IOP インターフェース経由で個々の ROM バンクに書き込むことも可能で、カスタム ROM のテストに使用できます。

Z80 アドレスデコード

64KB の Z80 アドレス空間は、マシンファミリーごとに異なるデコードが行われます。mz80k_hw および mz80b_hw モジュールが、CONFIG マシンタイプと Z80 アドレスに基づいてチップセレクトを生成します。

MZ-80A(代表的なパーソナルシリーズ):

アドレス範囲 コンポーネント チップセレクト
0x0000-0x0FFF モニター ROM CS_ROM_n
0x1000-0xCFFF ユーザー RAM (48KB) CS_RAM_n
0xD000-0xD7FF VRAM (2KB) CS_VRAM_n
0xD800-0xDFFF カラーアトリビュート RAM CS_ARAM_n
0xE000-0xE007 i8255 PPI CS_IO_PPI_n
0xE008-0xE00B i8254 PIT CS_IO_PIT_n
0xE800-0xEFFF ユーザー ROM(オプション) CS_USERROM_n
0xF000-0xFFFF FDC ROM(オプション) CS_FDCROM_n

MZ-700(カラーパーソナルシリーズ):

アドレス範囲 コンポーネント チップセレクト
0x0000-0x0FFF モニター ROM(起動後バンクアウト) CS_ROM_n
0x0000-0xFFFF 64KB RAM(ROM バンクアウト後) CS_RAM_n
0xD000-0xD7FF VRAM CS_VRAM_n
0xD800-0xDFFF カラーアトリビュート RAM CS_ARAM_n
0xE000-0xE003 i8255 PPI CS_IO_PPI_n
0xE004-0xE007 i8254 PIT CS_IO_PIT_n
0xE008 メモリバンク制御 CS_BANKCTL_n

MZ-80B/2000(ビジネスシリーズ):

アドレス範囲 コンポーネント チップセレクト
0x0000-0x07FF IPL ROM(起動時、その後バンクアウト) CS_IPL_n
0x0000-0xFFFF 64KB RAM CS_RAM_n
0xD000-0xDFFF VRAM (4KB) CS_VRAM_n
0xE000-0xFFFF GRAM アクセスウィンドウ CS_GRAM_n
I/O 0xD8-0xDB i8255 PPI CS_IO_PPI_n
I/O 0xD4-0xD7 i8254 PIT CS_IO_PIT_n
I/O 0xF4-0xF7 Z80 PIO CS_IO_PIO_n
I/O 0xF8-0xFD グラフィックス制御 CS_IO_GRAM_n

CPU データバスマルチプレクシング

T80 のデータ入力は、すべてのメモリおよびペリフェラルソースからマルチプレクスされます:
T80_DI <= SYSROM_DO       when CS_ROM_n     = '0' else
          SYSRAM_DO       when CS_RAM_n     = '0' else
          VIDEO_DO        when CS_VRAM_n    = '0' else
          ARAM_DO         when CS_ARAM_n    = '0' else
          PPI_DO          when CS_IO_PPI_n  = '0' else
          PIT_DO          when CS_IO_PIT_n  = '0' else
          FDD_DO          when CS_FDD_n     = '0' else
          (others => '1');  -- Open-drain pullup simulation
デフォルトの '1' は実際のハードウェアのオープンドレインバス動作をシミュレートしており、非選択デバイスは High にフロートします。

Part 10 — カセットテープサブシステム

cmt モジュール(1806行)は、すべての Sharp MZ モデル用のカセットテープインターフェースをエミュレートします。PWM ビットエンコーディング/デコーディング(オリジナルハードウェアのマンチェスタ風エンコーディングに一致)、テープモーター制御、MZ-2000 用の APSS(Automatic Program Search System)、および I/O Processor が管理するテープデータキューを実装しています。

CMT バス信号

出力信号(CMT_BUS_OUT, 17ビット — FPGA から I/O Processor へ):

ビット 定数 機能
0 PLAY_READY テープ再生バッファロード済み、再生準備完了
1 PLAYING テープ再生中
2 RECORD_READY 録音バッファフル(保存用データあり)
3 RECORDING テープ録音中
4 ACTIVE 転送アクティブ
5 SENSE Z80 PPI へのテープ状態センス出力
6 WRITEBIT Z80 に送信されるビット値(再生)
7 TAPEREADY 仮想デッキにカセット装着済み
8 WRITEREADY 書き込み許可
9 APSS_SEEK 次のプログラムのシーク開始(APSS_DIR に従う)
10 APSS_DIR シーク方向: 0=巻き戻し, 1=早送り
11 APSS_EJECT カセットイジェクト
12 APSS_PLAY カセット再生
13 APSS_STOP 再生/巻き戻し/早送り停止
14 APSS_AUTOREW テープ終端でのデッキ自動巻き戻し
15 APSS_AUTOPLAY APSS アクション後の自動再生
16 ENDOFTAPE テープ終端検出

入力信号(CMT_BUS_IN, 13ビット — Z80 マシンから CMT へ):

ビット 定数 機能
0 READBIT Z80 からのビット値(録音)
1 REEL_MOTOR APSS リールモーター オン/オフ
2 STOP モーター停止
3 PLAY 再生コマンド
4 SEEK シーク(FF/REW)
5 DIRECTION シーク方向: L=巻き戻し, H=早送り
6 EJECT カセットイジェクト
7 WRITEENABLE 録音有効化
8 AUTOPLAY 巻き戻し終了時の再生有効化
9 AUTOREW 自動巻き戻し有効化
10 CMTFF 早送り
11 CMTREW 巻き戻し
12 KINH キーボード禁止(FF/REW/STOP/EJECT をブロック)

テープデータフロー

I/O Processor (K64F)              FPGA (CMT module)                 Z80 CPU (T80)

Load .MZF file ─────────────────→ CMT DATA RAM (64KB) ─── PWM ──→ READBIT → i8255 PPI
 │                                 CMT HDR RAM (128B)               (Port C bit)
 │ (IOP writes via IOP_CMT0_CSn)
 │
 │                                 CMT DATA RAM ←──── PWM ←─────── WRITEBIT → PPI
Save .MZF file ←────────────────── CMT HDR RAM                     (recording)
 (IOP reads via IOP_CMT1_CSn)

MZF テープフォーマット

Sharp MZ テープフォーマット(.MZF)は 128バイトのヘッダとそれに続くデータ本体で構成されます:
オフセット サイズ 内容
0x00 1 ファイルタイプ (01=binary, 02=MZ-80K BASIC, 03=data, 05=MZ-700 binary)
0x01 17 ファイル名(Sharp ASCII、0x0D でパディング)
0x12 2 ファイルサイズ(リトルエンディアン)
0x14 2 ロードアドレス(リトルエンディアン)
0x16 2 実行アドレス(リトルエンディアン)
0x18 104 コメント/パディング
0x80+ N データ本体(N = ファイルサイズ)

速度オプション(FASTTAPE 設定)

CONFIG[64:62] 速度 ボーレート相当
000 1x(オリジナル) 1200 baud (MZ-80K) または 2400 baud (MZ-700)
001 2x やや高速なローディング
010 4x 実用的なローディング
011 8x クイックテスト
100 16x 開発用
101 32x ほぼ瞬間ロード

APSS (MZ-2000)

MZ-2000 は APSS(Automatic Program Search System)をサポートしており、テープデッキが自動的に次のプログラムまで早送りまたは巻き戻しできます。CMT モジュールは APSS_SEEK、APSS_DIR、APSS_PLAY、APSS_STOP 信号を使用して APSS ステートマシンを実装しています。I/O Processor はテープキュー(仮想テープ上に連結された複数の MZF ファイル)を管理し、APSS_SEEK がアサートされるとファイルポインタを進めます。

Part 11 — キーボードと入力

keymatrix モジュール(1222行)は、PS/2 キーボード入力をエミュレーション対象マシンが期待する Sharp MZ キーボードマトリクスに変換します。各 Sharp MZ モデルは異なるキーボードマトリクスレイアウトを使用しており、モジュールはそれぞれに対して個別の変換テーブルを保持しています。

PS/2 から Sharp MZ への変換

変換プロセスは2段階で動作します:
  1. PS/2 デコード: PS/2 シリアルプロトコルがスキャンコードにデコードされます。メイクコード(キー押下)とブレイクコード(キー解放)は 0xF0 プレフィクスバイトで区別されます。

  2. マトリクスマッピング: 各 PS/2 スキャンコードが Sharp MZ キーボードマトリクスの(行、列)ペアにマッピングされます。マッピングは I/O Processor がロードするルックアップテーブルに格納されており、マシンモデルごとにカスタマイズ可能です。

キーボードマトリクスサイズ

機種 マトリクスサイズ
MZ-80K/C/1200 10 8 80 キー
MZ-80A 10 8 80 キー(異なるレイアウト)
MZ-700 10 8 70 キー(削減)
MZ-80B/2000 10 8 80 キー(ビジネスレイアウト)

キースキャンプロトコル

Sharp MZ キーボードインターフェースは i8255 PPI を通じて動作します。Z80 がスキャン行番号を PPI Port A に書き込み、PPI Port B から列データを読み取ります。keymatrix モジュールはこれらの PPI トランザクションをインターセプトします:
-- When Z80 writes to PPI Port A, latch the scan row
MZ_KEYB_SCAN <= PPI_PORT_A(3 downto 0);

-- When Z80 reads PPI Port B, return the matrix column data for the active row
PPI_PORT_B <= KEYB_MATRIX(to_integer(unsigned(MZ_KEYB_SCAN)));

I/O Processor キーボードインターフェース

I/O Processor は IOP_KEYB_CSn を通じてキーボードマトリクスに直接書き込むことで、キーストロークを注入することもできます。これは自動テストや、OSD メニューナビゲーション(メニューシステムは K64F 上で実行され、メニュー項目を選択するための合成キーイベントを送信する)に使用されます。

Break キー検出

MZ_KEYB_BREAKDETECT 信号は、通常のマトリクススキャンをバイパスして、Break キーが押されたことを直接示します。これは I/O Processor がインタラクティブデバッグ用にエミュレーション CPU へ NMI をトリガするために使用されます。

Arbiter との連携

キーボードモジュールはスキャンを実行するためにバスアクセスが必要です — エミュレートされた Z80 バス上の PPI ポートを読み取る必要があります。arbiter がラウンドロビンスケジュールでキーボードにタイムスロットを付与します。MZ_KEYB_GRANTn 信号はキーボードがバスアクセスを持つことを示し、MZ_KEYB_BUSYn はキーボードがまだバスを使用中であることを arbiter に伝えます。

Part 12 — サウンドサブシステム

snd モジュール(369行)は、MZ-700 および MZ-800 が使用する SN76489 サウンドジェネレータと、MZ-80K/C/1200/80A ファミリーが使用する i8253/i8254 タイマーベースのオーディオを組み合わせたオーディオサブシステムを実装しています。オーディオ出力はアナログ出力ピンを駆動するシグマデルタ DAC または PWM DAC 経由です。

サウンドソース

ソース コンポーネント 対象機種 機能
i8254 Counter 0 Programmable Interval Timer 全パーソナルシリーズ 矩形波トーンジェネレータ
SN76489 Texas Instruments PSG MZ-700, MZ-800 3トーンチャンネル + 1ノイズ
i8253(ビジネス) Timer MZ-80B, MZ-2000 PIT カスケード経由の矩形波

SN76489 統合

SN76489 PSG(Programmable Sound Generator)は、3つの独立したトーンジェネレータと1つのノイズジェネレータを提供します。各トーンチャンネルには 10ビットの周波数分周器と 4ビットの音量アッテネータがあります。ノイズチャンネルはホワイトノイズとペリオディックノイズモードをサポートします。モジュールはオープンソースの SN76489 VHDL コアを使用しています。

オーディオミキシングと出力

CONFIG バスがオーディオソース選択とミキシングを制御します:
CONFIG ビット 機能
[51] AUDIOSRC 0=サウンドジェネレータ, 1=テープオーディオ
[55:52] AUDIOVOL 16段階音量制御
[57:56] AUDIOMIX 左右チャンネルブレンド
[58] AUDIOHW ホスト(0) または FPGA(1) オーディオハードウェア使用
最終オーディオはシグマデルタ DAC(sigma_delta_dac モジュール)を通じて出力され、デジタルオーディオサンプルを 1ビット PWM ストリームに変換します。これは PCB 上でローパスフィルタされ、アナログオーディオ信号を生成します。

Arbiter との連携

キーボードと同様に、サウンドモジュールも時折バスアクセスが必要です(Z80 からの I/O レジスタ書き込みを処理するため)。arbiter が MZ_SND_GRANTn / MZ_SND_BUSYn を通じてスロットを付与します。

Part 13 — フロッピーディスクコントローラ

fdd モジュール(355行)は、MZ-80B、MZ-2000、および MZ-800(オプションのフロッピーディスクインターフェース付き)が使用する Western Digital WD1793 フロッピーディスクコントローラをエミュレートします。モジュールは WD1793 レジスタセットとコマンドステートマシンを実装し、実際のディスクイメージデータは I/O Processor が SD カードから提供します。

WD1793 レジスタマップ

アドレスオフセット 読み出し 書き込み
0 ステータスレジスタ コマンドレジスタ
1 トラックレジスタ トラックレジスタ
2 セクタレジスタ セクタレジスタ
3 データレジスタ データレジスタ

ドライブ設定

最大4台の仮想ドライブがサポートされ、CONFIG バスで設定されます:
CONFIG ビット 機能
[26] FDDENABLE FDD サブシステムのマスター有効化
[27] FDDINTEN FDD 操作時の割り込み生成有効化
[31:28] FDDDISKREADY ドライブごとのディスク装着状態(4ビット、ドライブごとに1ビット)
[35:32] FDDPOLARITY ドライブごとのデータ極性(反転 vs. 通常)
[39:36] FDDWRPROTECT ドライブごとのライトプロテクト

データフロー

I/O Processor がディスクイメージを管理します。WD1793 がセクタ読み取りコマンドを受信すると:
  1. FDD モジュールが iointr モジュール経由で I/O Processor に割り込みを生成します。
  2. I/O Processor が SD カード上のディスクイメージファイルから要求されたトラック/セクタ/サイドを読み取ります。
  3. I/O Processor が IOP_FDD_CSn 経由で FDD のデータバッファにセクタデータを書き込みます。
  4. FDD モジュールが適切な DRQ(Data Request)タイミングで WD1793 データレジスタにバイト単位でデータを提示します。
書き込み操作はフローが逆になります — FDD モジュールが Z80 からデータを受け取ってバッファリングし、I/O Processor に割り込みを発行してセクタをディスクイメージに書き戻させます。

FDC クロック

WD1793 は内部タイミング(ステップレート、ヘッドロードなど)用に独立したクロックを必要とします。これは CLKBUS[6](CKENFDC)から提供され、通常 8MHz です。

Part 14 — バスアービトレーション

arbiter モジュール(653行)は、エミュレートされた Z80 バス用のラウンドロビンバスアービトレーションサービスを提供します。emuMZ モードでは、複数のエージェントがエミュレートされたバスへのアクセスを必要とします — T80 CPU、キーボードスキャナ、CMT インターフェース、割り込みジェネレータ、サウンドモジュールです。arbiter はバスコンテンションを防ぐためにこれらのリクエストをシリアライズします。

アービトレーション方式

arbiter は、デフォルトバスマスタとしての T80 CPU に加え、4つのバスエージェントを持つラウンドロビン優先方式を使用します:
エージェント Grant 信号 Busy 信号 Reset 信号 優先スロット
T80 CPU (デフォルトマスタ) プリエンプトされない限り常にアクティブ
キーボード MZ_KEYB_GRANTn MZ_KEYB_BUSYn MZ_KEYB_RESETn 0
CMT MZ_CMT_GRANTn MZ_CMT_BUSYn MZ_CMT_RESETn 1
割り込み MZ_INTR_GRANTn MZ_INTR_BUSYn MZ_INTR_RESETn 2
サウンド MZ_SND_GRANTn MZ_SND_BUSYn MZ_SND_RESETn 3

プロトコル

バスアクセスが必要な各エージェントは BUSYn 信号を Low にアサートします(バス要求)。arbiter はラウンドロビン順でエージェントを巡回し、次にリクエストしているエージェントに対して GRANTn を Low にアサートします。付与されている間、エージェントはエミュレートされたバス(アドレス、データ、制御)を駆動してトランザクションを実行します。完了するとエージェントが BUSYn をデアサートし、arbiter は次のスロットに移動します。

T80 ウェイトステート挿入

T80 以外のエージェントがバスを占有しているとき、arbiter は MEMWAITn を Low にアサートし、T80 を WAIT 入力を介してフリーズさせます。これにより、バスが占有されている間に T80 がメモリまたは I/O サイクルを試行しないことが保証されます。ウェイトステートは実行中の Z80 ソフトウェアに対して透過的です — 現在のバスサイクルが単に延長されるだけです。

ウォッチドッグタイマ

arbiter には 1秒のウォッチドッグが含まれています。いずれかのエージェントが BUSYn をデアサートせずに約1秒以上バスを保持した場合、arbiter はそのエージェントを(RESETn 信号を通じて)強制的にリセットし、バスを解放します。これにより、ハングしたペリフェラルがエミュレーション全体をロックアップすることを防ぎます。

I/O Processor バスリクエスト

I/O Processor(K64F)も arbiter への BUSRQn 入力を通じてバスを要求できます。これはラウンドロビンエージェントよりも高い優先度を持ち、I/O Processor が ROM イメージのロードやテープデータバッファの読み書きなどの操作を行う必要がある場合に使用されます。I/O Processor がバスを付与されると、T80 は BUSRQ を受け取り、I/O Processor が処理を進める前に BUSACK でアクノレッジする必要があります。

初期化

ARB_INIT 出力信号は初期パワーアップシーケンス中にパルスし、T80 が実行を開始する前にすべてのエージェントがステートマシンを同期できるようにします。

Part 15 — I/O Processor インターフェース

I/O Processor(IOP)インターフェースは、K64F ARM Cortex-M4 マイクロコントローラと FPGA 間の通信パスです。チップセレクト、アドレス、データ、リード/ライト制御信号を持つパラレルバスを使用します。

物理信号

信号 ビット幅 方向 機能
IOP_CSn(複数) 各1 K64F → FPGA 各モジュールのチップセレクト(アクティブ Low)
IOP_ADDR[5:0] 6 K64F → FPGA 選択モジュール内のレジスタアドレス
IOP_DIN[7:0] 8 K64F → FPGA 書き込みデータ
IOP_DOUT[7:0] 8 FPGA → K64F 読み出しデータ
IOP_WRn 1 K64F → FPGA 書き込みストローブ(アクティブ Low)
IOP_RDn 1 K64F → FPGA 読み出しストローブ(アクティブ Low)

チップセレクトマップ

チップセレクト モジュール レジスタ数 用途
IOP_MCTRL_CSn mctrl 16 マシン設定、リセット
IOP_MZ80K_CSn mz80k_hw 16 パーソナルシリーズ PPI/PIT 設定
IOP_MZ80B_CSn mz80b_hw 16 ビジネスシリーズ PPI/PIT/PIO 設定
IOP_KEYB_CSn keymatrix 16 キーボードマトリクス注入、マッピング
IOP_FDD_CSn fdd 16 FDD データ転送、ステータス
IOP_CMT0_CSn cmt(書き込み) 64 CMT データ書き込み(テープロード)
IOP_CMT1_CSn cmt(読み出し) 64 CMT データ読み出し(テープ保存)
IOP_INTR_CSn iointr 16 割り込みアクノレッジ、ベクタ読み出し
IOP_SND_CSn snd 16 サウンド設定

トランザクションプロトコル

代表的な IOP 書き込みトランザクション:
  1. K64F がターゲットモジュールの CSn を Low にセットします。
  2. K64F が IOP_ADDR にレジスタオフセットを駆動します。
  3. K64F が IOP_DIN にデータバイトを駆動します。
  4. K64F が IOP_WRn を少なくとも 2 CKMASTER サイクル間 Low にアサートします。
  5. K64F が IOP_WRn をデアサートします。
  6. K64F が CSn を解放します。
代表的な IOP 読み出しトランザクション:
  1. K64F がターゲットモジュールの CSn を Low にセットします。
  2. K64F が IOP_ADDR にレジスタオフセットを駆動します。
  3. K64F が IOP_RDn を Low にアサートします。
  4. FPGA が IOP_DOUT にレジスタ値を駆動します(1 CKMASTER サイクルのレイテンシ)。
  5. K64F が IOP_DOUT を読み取ります。
  6. K64F が IOP_RDn と CSn をデアサートします。

データ出力マルチプレクシング

各モジュールは独自の IOP_xxx_DOUT 信号を生成します。トップレベルエンティティが、アクティブなチップセレクトに基づいてこれらをマルチプレクスします:
IOP_DOUT <= IOP_MCTRL_DOUT when IOP_MCTRL_CSn = '0' else
            IOP_MZ80K_DOUT when IOP_MZ80K_CSn = '0' else
            IOP_MZ80B_DOUT when IOP_MZ80B_CSn = '0' else
            IOP_KEYB_DOUT  when IOP_KEYB_CSn  = '0' else
            IOP_FDD_DOUT   when IOP_FDD_CSn   = '0' else
            IOP_CMT0_DOUT  when IOP_CMT0_CSn  = '0' else
            IOP_CMT1_DOUT  when IOP_CMT1_CSn  = '0' else
            IOP_INTR_DOUT  when IOP_INTR_CSn  = '0' else
            IOP_SND_DOUT   when IOP_SND_CSn   = '0' else
            (others => '1');

Part 16 — 割り込みシステム

iointr モジュール(325行)は、FPGA エミュレーションモジュールと I/O Processor 間の割り込み集約およびキューイングサービスを提供します。最大8つの独立した割り込みソースを受け付け、FIFO にキューイングし、K64F への単一の割り込み出力を生成します。

割り込みソース

入力 ソース 代表的なトリガ
INTR0n CMT モジュール テープバッファ空(リフィル必要)またはフル(保存必要)
INTR1n FDD モジュール セクタ読み書きリクエスト
INTR2n キーボード Break キー検出
INTR3n mctrl マシンモデル変更通知
INTR4n サウンド バッファアンダーラン
INTR5n-7n 予約 将来の拡張用

FIFO キュー

各割り込みソースは FIFO へのシングルエントリ書き込みをトリガします。FIFO は割り込みソース番号(3ビット)をリーズンコードとして格納します。K64F が割り込みリーズンレジスタを読み取ると(IOP_INTR_CSn 経由)、キューイングされた最古の割り込みを受け取り、そのエントリがデキューされます。これにより、K64F がすぐに応答できない場合でも、複数の割り込みを順序通りにサービスすることが可能です。

割り込み処理フロー

  1. ペリフェラル(例: CMT)が INTRn 信号を Low にアサートします。
  2. iointr モジュールがソース番号をラッチし、FIFO にプッシュします。
  3. iointr モジュールが K64F への集約割り込み出力をアサートします。
  4. K64F の割り込みハンドラが IOP_INTR_CSn 経由でリーズンレジスタを読み取ります。
  5. リーズンコードに基づき、K64F が必要なサービスを実行します(例: 次のテープブロックのロード)。
  6. K64F がアクノレッジを書き込み、割り込みをクリアします。
  7. FIFO にさらにエントリが残っている場合、割り込みはアサートされたままです。

Arbiter との連携

iointr モジュール自体も、割り込みアクノレッジサイクル(M1 + IORQ)中に Z80 バスに割り込みベクタを書き込むためにバスアクセスが必要です。これは MZ_INTR_GRANTn / MZ_INTR_BUSYn メカニズムを通じてアービトレートされます。

Part 17 — CPLD バスマネージャ

CPLD(MAX7000AE EPM7512AETC144-10)は、Sharp MZ メインボードの 5V バスと 3.3V FPGA および SRAM の間に位置します。FPGA コンフィギュレーションレイテンシに耐えられないすべてのタイミングクリティカルなグルーロジックを処理し、すべてのトランザクションの最初のレベルのバスデコードを提供します。

CPLD ソースファイル

ファイル 用途
tranZPUterSW700.vhd (MZ-700) / tzpuSW700_MZ80A.vhd (MZ-80A) メインアーキテクチャ
tranZPUterSW700_Toplevel.vhd トップレベルエンティティ、I/O ピンアサイン
tranZPUterSW700_pkg.vhd パッケージ(定数、型定義)

CPLD 設定レジスタ (I/O 0x6E)

ビット 機能
[2:0] ビデオモード: 000=MZ-80K, 001=MZ-80C, 010=MZ-1200, 011=MZ-80A, 100=MZ-700, 101=MZ-800, 110=MZ-80B, 111=MZ-2000
[3] メインボードビデオ有効化(1=メインボードビデオアクティブ)
[4] WAIT ステート有効化
[7] 設定保持(リセットによるモードレジスタクリアを防止)

CPLD の主要機能

レベル変換とバスインターフェース: CPLD は Z80_* 信号(5V、メインボード側)から VZ80_* 信号(3.3V、FPGA 側)を駆動します。メインボード側のすべてのピンは 5V トレランスで動作し、FPGA 側のすべてのピンは 3.3V を駆動します。
BUSRQ/BUSACK ハンドシェイク: FPGA(または K64F)がメインボードバスの制御を必要とする場合、CPLD が Z80 BUSRQ/BUSACK プロトコルを管理します。S-R ラッチがバスマスタ状態間のグリッチフリーな遷移を保証します。
クロック周波数切替: 2つの D フリップフロップがグリッチフリーなクロックマルチプレクサを実装します。Z80 はメインボード SYSCLK(オリジナル速度)または CTLCLK(K64F からのプログラマブル周波数)のいずれかで動作できます。切替は両方のクロックがアイドルになるのを待ちます。
TZMM モードレジスタ (MEM_MODE_LATCH): 8ビットのメモリモードラッチ(I/O ポート 0x60)は、512KB SRAM のどの 64KB ページが Z80 アドレス空間にマッピングされるかを選択します。ビット [4:0] は Z80_MEM[4:0] として FPGA に転送されます。ビット 5 は I/O ウェイトステートジェネレータを有効にします。
I/O アドレスデコード: CPLD は tranZPUter I/O 範囲 0x60-0x6F への書き込みを、FPGA の CPU 設定、CPLD 設定、メモリモード、ビデオ制御レジスタ用の個別チップセレクト信号にデコードします。
ビデオアクセスデコード: CPLD はビデオ RAM アドレス範囲(通常 D000-DFFF)へのメモリアクセスをデコードして VIDEO_RDnVIDEO_WRn 信号を生成し、FPGA ビデオコントローラへの専用ストローブとして転送します。

ビルドバリアント

CPLD プロジェクト ホストマシン 相違点
tranZPUterSW700 MZ-700 デフォルト I/O デコード、カラービデオアクセス
tzpuSW700_MZ80A MZ-80A MZ-80A メモリマップ用に修正された I/O デコード
tzpuSW700_MZ2000 MZ-2000 ビジネスシリーズのバスタイミング、GRAM アクセスデコード
CPLD は Quartus Prime 13.0 SP1(MAX7000AE をサポートする最後のバージョン)を使用して CPLDfit フィッタでビルドされます。プログラミングには JTAG モードで標準 USB-Blaster ケーブルを使用します。

Part 18 — パーソナルシリーズハードウェア

mz80k_hw モジュール(1416行)は、パーソナルシリーズの Sharp MZ コンピュータ(MZ-80K、MZ-80C、MZ-1200、MZ-80A、MZ-700、MZ-800)のハードウェアを実装しています。Z80 アドレスデコーダ、I/O アドレスデコーダを含み、マシン固有のペリフェラルをインスタンス化します。

ペリフェラル

コンポーネント インスタンス 機能
i8255 PPI キーボードスキャン(Port A)、キーボードデータ(Port B)、カセット/サウンド制御(Port C)
i8254 PIT Counter 0 = サウンドトーン、Counter 1 = カスケード、Counter 2 = RTC

I/O アドレスマップ(パーソナルシリーズ)

アドレス 読み出し 書き込み 機種
0xE000 PPI Port A(キースキャン) PPI Port A 全機種
0xE001 PPI Port B(キーデータ) PPI Port B 全機種
0xE002 PPI Port C(ステータス) PPI Port C(制御) 全機種
0xE003 PPI 制御ワード 全機種
0xE004-E007 PIT Counter 0-2 + 制御 PIT Counter 0-2 + 制御 全機種
0xE008 メモリバンク制御 MZ-700 のみ
0xE9 グラフィックスバンクスイッチリセット MZ-700/800(GRAM 付き)
0xEA グラフィックス制御 グラフィックス制御 MZ-700/800(GRAM 付き)

メモリバンキング (MZ-700)

MZ-700 はアドレス 0xE008 への書き込みで制御される独自のメモリバンキング方式を使用します。起動時にはモニター ROM が 0x0000-0x0FFF を占有し、プログラムロード後は ROM がバンクアウトされ、64KB RAM 全体がアクセス可能になります。さらに、MZ-700 は 0xD000-0xDFFF の VRAM/ARAM と 0xE000-0xFFFF の I/O をバンクイン/バンクアウトできます:
バンク制御書き込み 効果
0xE0 to 0xE000 ROM バンクアウト、0x0000 に RAM バンクイン
0xE1 to 0xE000 0x0000 に ROM バンクイン
0xE2 to 0xE000 VRAM/IO バンクアウト、0xD000-0xFFFF に RAM バンクイン
0xE3 to 0xE000 0xD000-0xFFFF に VRAM/IO バンクイン

マシン固有の差異

CONFIG[10:0] CURRENTMACHINE ビットがエミュレーションするマシンモデルを選択します。mz80k_hw モジュールはこれらのビットを使用して以下を行います:
  • SYSROM から正しい ROM バンクを選択
  • カラーアトリビュート RAM の有効/無効化(モノクロマシンには ARAM がない)
  • PPI Port C のビットアサインを設定(MZ-80K と MZ-700 で異なる)
  • SN76489 サウンドの有効/無効化(MZ-700/800 のみ)
  • PCG サポートの設定(PCG オプション付き MZ-700)

Part 19 — ビジネスシリーズハードウェア

mz80b_hw モジュール(676行)は、ビジネスシリーズ(MZ-80B、MZ-2000、MZ-2200、MZ-2500)のハードウェアを実装しています。これらのマシンはパーソナルシリーズとは根本的に異なるアーキテクチャを持ち、IPL ブート ROM、Z80 PIO、80桁表示、3プレーングラフィックス RAM、APSS 対応カセットインターフェースを備えています。

追加ペリフェラル

コンポーネント インスタンス 機能
i8255 PPI パーソナルシリーズと同様だが異なるポートアサイン
i8254 PIT タイミング用カウンタカスケードモード
z8420 PIO Z80 Parallel I/O — 割り込み駆動の入出力

I/O アドレスマップ(ビジネスシリーズ)

アドレス 機能 備考
0xD4-0xD7 i8254 PIT パーソナルシリーズとは異なるベースアドレス
0xD8-0xDB i8255 PPI ビジネスシリーズ設定
0xDC-0xDD メモリ制御 RAM/ROM バンキング
0xE0-0xE3 CRTC / ビデオ制御 表示タイミングレジスタ
0xE4-0xE7 予約
0xE8-0xED グラフィックス制御 フレームバッファバンク/カラー選択
0xF4-0xF7 Z80 PIO Port A/B データおよび制御レジスタ
0xFE-0xFF IPL / ブート制御 IPL ROM 有効化/無効化

グラフィックスフレームバッファ

MZ-80B/2000 グラフィックスサブシステムは、3つの独立したフレームバッファプレーン(Red、Green、Blue)を提供し、各 16KB で、バンク切替を通じて 0xC000-0xFFFF の Z80 アドレス空間にマッピングされます:
レジスタ アドレス 機能
0xE8 グラフィックスバンクスイッチセット C000-FFFF ウィンドウ用 R/W バンク (R/G/B) 選択
0xE9 グラフィックスバンクスイッチリセット バンク選択解除
0xEA 制御レジスタ 読み出しバンク選択、書き込みバンク選択、VRAM/GRAM 有効化、ブレンドオペレータ
0xEB Red カラーライタ 赤プレーンへのバイト書き込み
0xEC Green カラーライタ 緑プレーンへのバイト書き込み
0xED Blue カラーライタ 青プレーンへのバイト書き込み
カラーライタレジスタにより、単一の I/O 命令で1つまたは複数のプレーンに同時書き込みが可能で、高速な画面フィルやカラー設定操作を実現します。

IPL ブートシーケンス

MZ-80B と MZ-2000 は、ブート時のみアクティブな IPL(Initial Program Load)ROM を使用します。CONFIG[73] BOOT_RESET がセットされると、IPL ROM がアドレス 0x0000 に出現します。IPL がカセット(または FDD)からモニターをロードした後、IPL ROM をバンクアウトしてロードされたコードにジャンプします。BOOT_RESET 設定により、I/O Processor がクリーンなブートサイクルをトリガできます。

Part 20 — グラフィックスフレームバッファ

グラフィックスフレームバッファは、パーソナルシリーズ(GRAM オプション付き MZ-700/800)とビジネスシリーズ(MZ-80B/2000 ネイティブ)の両方で使用される共有サブシステムです。独立してアドレス指定でき、文字表示と合成可能な3つの 16KB フレームバッファプレーンを提供します。

メモリレイアウト

プレーン FPGA アドレス サイズ Z80 アクセス
Red 0x240000-0x243FFF 16KB バンクスイッチレジスタ (0xE8/0xE9) 経由
Blue 0x250000-0x253FFF 16KB バンクスイッチレジスタ経由
Green 0x260000-0x263FFF 16KB バンクスイッチレジスタ経由

ブレンドモード(制御レジスタ 0xEA)

モードビット 操作 説明
00 Replace グラフィックスピクセルが文字表示を置換
01 OR グラフィックスと文字表示の OR
10 AND グラフィックスと文字表示の AND
11 XOR グラフィックスと文字表示の XOR

カラーライタ操作

カラーライタレジスタ(0xEB-0xED)は、複数プレーンのピクセルカラーを同時に設定するためのハードウェアアクセラレーション手段を提供します。Red カラーライタ(0xEB)にバイトを書き込むと、Red プレーンの水平8ピクセルが設定されます。Green(0xEC)および Blue(0xED)への書き込みも、それぞれのプレーンに同様の操作を行います。各プレーン内のアドレスは、0xC000-0xFFFF ウィンドウにおける Z80 の現在のアドレスで設定されます:
-- Colour writer: when Z80 writes to colour register, the value is
-- written to the corresponding plane at the current GRAM address.
if CS_GRAM_WR = '1' then
    case GRAM_BANK is
        when "001" => GRAM_RED(GRAM_ADDR)   <= Z80_DATA;
        when "010" => GRAM_GREEN(GRAM_ADDR) <= Z80_DATA;
        when "100" => GRAM_BLUE(GRAM_ADDR)  <= Z80_DATA;
        when others => null;
    end case;
end if;

GRAM オプション(CONFIG ビット)

CONFIG ビット 定数 機能
43 OPT_GRAMI MZ-80B GRAM I / MZ-2000 Blue 搭載
44 OPT_GRAMII MZ-80B GRAM II / MZ-2000 Red 搭載
45 OPT_GRAMIII MZ-2000 Green 搭載
46 OPT_PCG PCG (Programmable Character Generator) 搭載
47 OPT_MZ1R25 16KB Video RAM 拡張搭載

Part 21 — ステータスとメニューフレームバッファ

VideoController は2つの OSD(On-Screen Display)オーバーレイを提供します:ステータスバーと設定メニューです。両方とも専用のフレームバッファにレンダリングされ、エミュレーション表示の上に合成されます。

ステータスオーバーレイ

ステータスバーは画面下部を占有し、リアルタイム情報を表示します:現在のマシンモデル、CPU 速度、テープ状態、ドライブアクティビティなどです。CONFIG[72] STATUSENABLE で有効化されます。I/O Processor がアドレス 0x320000 のステータスフレームバッファにステータステキストを書き込みます。

メニューオーバーレイ

設定メニューにより、ユーザーはホストコンピュータなしでマシンモデル、表示モード、CPU 速度、オーディオ設定、その他のオプションを変更できます。CONFIG[71] MENUENABLE で有効化されます。I/O Processor がメニューステートマシンを管理し、レンダリングされたメニューをアドレス 0x322000 のメニューフレームバッファに書き込みます。

ビデオパラメータテーブル

アドレス 0x324000 の 32x32 パラメータテーブルに、モードごとの表示タイミングパラメータが格納されます。各エントリには水平/垂直の合計、アクティブ、同期開始/終了値が含まれます。VideoController は表示モードが変更されるとアクティブなエントリを読み取り、タイミングジェネレータを設定します。現在のビデオモードインデックスは 0x324400 に格納されます。

OSD 合成

アクティブ表示期間中、VideoController は現在のピクセル位置が OSD 領域内にあるかどうかをチェックします。OSD 領域内で対応する OSD ピクセルが非透過の場合、OSD カラーがエミュレーション出力を置き換えます。OSD は半透明の背景を使用し、あらゆるエミュレーション表示モードの上でも読みやすさを確保します。

Part 22 — 新しいエミュレーション対象機種の追加

本セクションでは、emuMZ エミュレータに新しい Sharp MZ モデル(または密接に関連する Z80 マシン)のサポートを追加するためのステップバイステップガイドを提供します。

ステップ 1: マシン定数の定義

mctrl_pkgmctrl.vhd の先頭)に新しいマシン定数を追加します:
constant MZ_NEW_MODEL : integer := 11;  -- Next available index after MZ2500
必要に応じて CURRENTMACHINE サブタイプ範囲を拡張します。

ステップ 2: ROM バンクの追加

新しいマシンのモニター ROM 用に SYSROM にバンクペアを割り当てます。ROM 初期化ファイル(combined_mrom.mif)を更新して、正しいオフセットにバイナリイメージを含めます。

ステップ 3: コントローラブランチの選択

新しいマシンがパーソナルシリーズ(mz80k_hw.vhd を拡張)またはビジネスシリーズ(mz80b_hw.vhd を拡張)のどちらに属するかを決定します。関連するコントローラのデコードロジックに新しい CONFIG マシンビットを追加します。

ステップ 4: メモリマップの定義

選択したコントローラに新しいマシンのメモリマップ用アドレスデコードロジックを追加します。CONFIG[10:0] マシンビットを使用して新しいデコードをゲートします:
if CONFIG(MZ_NEW_MODEL) = '1' then
    -- New machine's memory map
    CS_ROM_n  <= '0' when Z80_ADDR(15 downto 12) = "0000" else '1';
    CS_RAM_n  <= '0' when Z80_ADDR(15 downto 12) /= "0000" else '1';
    -- ... etc
end if;

ステップ 5: マシン固有ペリフェラルの追加

新しいマシンに設計にまだ存在しないペリフェラルがある場合、新しい VHDL モジュールを作成してコントローラにインスタンス化します。バスアクセスが必要な場合は arbiter に登録します。

ステップ 6: キーボードマッピングの更新

キーボードレイアウトが異なる場合、CONFIG マシンビットで選択される新しいマッピングテーブルを keymatrix.vhd に追加します。

ステップ 7: ビデオタイミングの更新

表示タイミングが異なる場合、VideoController に新しいタイミングパラメータセットを追加します。VideoController_pkg.vhd に新しいモード定数を追加します。

ステップ 8: I/O Processor の更新

K64F ファームウェアを更新して新しいマシンモデルを認識させます:ROM ファイル名、表示名、デフォルト設定値を追加します。OSD メニューのマシン選択リストに新しいモデルを含めるよう更新します。

ステップ 9: テスト

FPGA プロジェクトをビルドし、デバイスをプログラムし、OSD メニューで新しいマシンを選択して、モニター ROM が正しく実行されることを確認します。必要に応じてデバッグに Signal Tap やスロークロックを使用します。

Part 23 — ソースからのビルド

前提条件

ツール バージョン 用途
Intel Quartus Prime 17.1.1 (Lite or Standard) FPGA 合成、配置配線
Intel Quartus II 13.0 SP1 (Web Edition) CPLD 合成 (MAX7000AE)
USB-Blaster JTAG プログラミングケーブル
Docker Latest CI/CD 用コンテナ化ビルド環境

FPGA ビルド

FPGA プロジェクトファイルは FPGA/SW700/v1.3/MZ700/build/ にあります。各ビルドバリアントには独自の Quartus プロジェクトファイルがあります:
プロジェクトファイル ビルドバリアント トップエンティティ
coreMZ.qpf / coreMZ.qsf ビデオのみ coreMZ
coreMZ_SoftCPU.qpf / coreMZ_SoftCPU.qsf ビデオ + ソフト CPU coreMZ
coreMZ_emuMZ.qpf / coreMZ_emuMZ.qsf 完全エミュレーション coreMZ
手動ビルドの方法:
cd FPGA/SW700/v1.3/MZ700/build/
quartus_sh --flow compile coreMZ_emuMZ
ビルド成果物:
出力ファイル 用途
coreMZ_emuMZ.sof SRAM Object File — 揮発性 JTAG プログラミング
coreMZ_emuMZ.pof Programmer Object File — 不揮発性 EPCS プログラミング
coreMZ_emuMZ.rbf Raw Binary File — K64F 経由ロード用

CPLD ビルド

CPLD プロジェクトファイルは CPLD/ にあり、ターゲットマシンごとに1ディレクトリです:
cd CPLD/SW700/MZ700/build/
quartus_sh --flow compile tranZPUterSW700

ビルドマトリクス

FPGA ビルド(Quartus 17.1.1):

ターゲット FPGA バリアント 合計
SW700 v1.3 EP4CE115 coreMZ, coreMZ_SoftCPU, coreMZ_emuMZ 3
SW700 v1.3 EP4CE75 coreMZ, coreMZ_SoftCPU 2
Fusion v1.0 EP4CE115 coreMZ, coreMZ_SoftCPU, coreMZ_emuMZ 3
Fusion v1.0 EP4CE75 coreMZ, coreMZ_SoftCPU 2
3つのホストマシン(MZ-700、MZ-80A、MZ-2000)× FPGA バリアントを考慮すると、完全な SW700 FPGA ビルドマトリクスは 3マシン x 2 FPGA x 3モード = 18 ビルドになります。

CPLD ビルド(Quartus 13.0 SP1):

ターゲット ホスト CPLD プロジェクト
SW700 v1.3 MZ-700 tranZPUterSW700
SW700 v1.3 MZ-80A tzpuSW700_MZ80A
SW700 v1.3 MZ-2000 tzpuSW700_MZ2000
FusionX v1.0 MZ-700 tzpuFusionX (MZ700)
FusionX v1.0 MZ-80A tzpuFusionX (MZ80A)
FusionX v1.0 MZ-2000 tzpuFusionX (MZ2000)

Part 24 — Jenkins CI/CD パイプライン

ビルド概要

tranZPUter-Build Jenkins パイプラインは、FPGA および CPLD のビルドマトリクス全体を自動化し、バージョン管理されたリリースパッケージを生成します。パイプラインは master ブランチへの Gitea プッシュ Webhook によってトリガされます。
ステージ ツール 出力
Checkout Git (Gitea) tranZPUter ソースツリー
Version Gitea API 自動インクリメントされたバージョン番号
FPGA Build (×N) Quartus 17.1.1 (Docker) バリアントごとの .sof, .pof, .rbf
CPLD Build (×N) Quartus 13.0.1 (Docker) ターゲットごとの .pof
Package tar/gz バージョン管理されたリリースアーカイブ
Release Gitea API ダウンロード可能なアセット付きタグ付きリリース

Docker ビルド環境

イメージ バージョン 用途
quartus-prime-17.1.1 Intel Quartus Prime 17.1.1 Lite Cyclone IV 用 FPGA 合成
quartus-ii-13.0.1 Intel Quartus II 13.0 SP1 MAX7000AE 用 CPLD 合成

ビルドのトリガ

  • 自動: master ブランチへの Gitea プッシュ Webhook
  • 手動: https://jenkins.eaw.app/job/tranZPUter-Build/ の Jenkins “Build Now”

ビルドアーティファクト

各ビルドはマトリクス内のすべてのバリアントのプログラミングファイルを生成します。リリースパッケージには以下が含まれます:
  • マシン/FPGA/バリアントの各組み合わせ用 FPGA .sof/.pof/.rbf ファイル
  • 各マシンターゲット用 CPLD .pof ファイル
  • ROM 初期化ファイル (combined_mrom.mif)
  • リリースノート

Part 25 — 開発ワークフロー

編集・コンパイル・テストサイクル

一般的な開発ワークフローは以下の通りです:
  1. VHDL 編集 — テキストエディタまたは Quartus で関連するソースファイルを修正します。
  2. コンパイルquartus_sh --flow compile coreMZ_emuMZ を実行します(または Quartus GUI の “Start Compilation” を使用)。完全な emuMZ ビルドには最新のワークステーションで約15-25分かかります。
  3. プログラム — USB-Blaster を JTAG ヘッダに接続します。quartus_pgm または Quartus Programmer で .sof ファイルをロードします。JTAG プログラミングは約10秒で完了し、揮発性です(電源オフで失われます)。
  4. テスト — ホストマシンの電源を入れます。FPGA が JTAG イメージからロードされ、エミュレーションが開始されます。OSD メニュー(コンパイルに含まれている場合)を使用してマシンモデルを選択し、動作を確認します。
  5. 反復 — 問題が見つかった場合はステップ 1 に戻ります。FPGA 内部の問題の場合は Signal Tap をデバッグに使用します。

デバッグ技法

技法 ツール ユースケース
Signal Tap Quartus (JTAG) 内部 FPGA 信号をフルスピードでキャプチャ、波形を表示
スロークロック CONFIG デバッグレジスタ CPU を 0.1-100Hz に設定し、人間が観察可能な実行速度に
LED インジケータ ボード LED バス状態、モード、エラーのクイックステータス表示
IOP レジスタダンプ K64F シリアルコンソール CONFIG、CMT ステータス、arbiter 状態の読み戻し
VRAM 検査 IOP VRAM リード ビデオメモリの内容が期待される状態と一致することを確認
ロジックアナライザ 外部プローブ 外部バス信号(VZ80_ADDR、VZ80_DATA 等)をキャプチャ

Signal Tap セットアップ

Signal Tap II は Quartus の内蔵ロジックアナライザです。emuMZ ビルドに追加するには:
  1. Quartus プロジェクト (coreMZ_emuMZ.qpf) を開きます。
  2. Tools → Signal Tap II Logic Analyzer に移動します。
  3. 対象の信号を追加します(例: T80_ADDR, T80_DATA_OUT, CORE_MREQn, CLKBUS)。
  4. サンプルクロックを CLKBUS(CKMASTER) に設定し、サンプル深度を設定します(使用可能なブロック RAM により制限)。
  5. トリガ条件を定義します(例: T80_ADDR = 0x0000 でリセット後の最初の命令フェッチをキャプチャ)。
  6. 再コンパイル — Signal Tap がインストゥルメンテーションロジックを追加し、キャプチャバッファにブロック RAM を使用します。
  7. FPGA をプログラムし、Signal Tap GUI からキャプチャを実行します。
注意: Signal Tap はブロック RAM を消費します。EP4CE75 では emuMZ ビルドがメモリ制限を超える可能性があります。Signal Tap セッションには EP4CE115 を使用してください。

タイミング解析

コンパイル後、必ず Quartus Timing Analyzer レポートを確認してください。SDC 制約ファイル(coreMZ_emuMZ_constraints.sdc)がすべてのクロック関係を定義します。確認すべき主要項目:
  • すべてのセットアップ/ホールド要件が満たされていること(負のスラックがないこと)
  • CKMASTER からレジスタへのパスが 128MHz でタイミングを満たすこと
  • クロスドメインパス(CLOCK_50 から PLL 出力)が適切に制約されていること

Part 26 — 設計の拡張

新しいペリフェラルの追加

エミュレーションに新しいペリフェラルを追加するには:
  1. VHDL モジュールの作成 — 既存のモジュールパターンに従います:CLKBUS、CONFIG、IOP、バス信号を持つエンティティ、CKMASTER 上のクロックドプロセスを持つアーキテクチャ。

  2. IOP チップセレクトの追加 — ペリフェラルが I/O Processor アクセスを必要とする場合、トップレベルエンティティに新しい IOP_xxx_CSn 信号を追加し、K64F のチップセレクトデコーダに接続します。

  3. Arbiter への登録 — ペリフェラルがエミュレートされたバスアクセスを必要とする場合、arbiter に新しいエージェントスロットを追加します。新しい GRANT/BUSY/RESET 信号トリプレットでラウンドロビンを拡張します。

  4. トップレベルへの接続coreMZ_emuMZ.vhd で新しいモジュールをインスタンス化し、適切な内部信号にポートを配線します。

  5. QIP への追加 — Quartus がコンパイルに含めるよう、新しい VHDL ファイルを coreMZ_emuMZ.qip ファイルリストに追加します。

  6. CONFIG の更新 — ペリフェラルに設定ビットが必要な場合、mctrl_pkg で CONFIG バスを拡張し、mctrl.vhd に対応する IOP レジスタを追加します。

メモリ拡張

emuMZ バリアントは FPGA ブロック RAM のみを使用します。メモリを追加するには:
  • ブロック RAM: 追加の dpram モジュールをインスタンス化します。FPGA 使用率を確認してください — EP4CE115 は合計 3,981 Kbits です。
  • 外部 SRAM: CPLD 経由でルーティングします。CPLD デコードロジックと FPGA トップレベルエンティティの変更が必要で、SRAM アドレス/データ/制御信号を追加します。
  • SDRAM コントローラ: devices/sysbus/SDRAM/ ディレクトリに W9864G6 および 48LC16M16 デバイス用の SDRAM コントローラ IP が含まれています。大容量メモリアプリケーション(例: 数メガバイトの RAM を持つ ZPU Evolution)にインスタンス化できます。

新しい FPGA への移植

VHDL は大部分がポータブルです。変更が必要なプラットフォーム固有の項目:
項目 ファイル 変更内容
PLL PLL/ ディレクトリ Altera PLL メガファンクションをターゲットベンダーの同等品に置換
ブロック RAM dpram.vhd, BRAM テンプレート Altera RAM メガファンクションを置換
SFL SFL/ ディレクトリ Serial Flash Loader — 削除または置換
ピンアサイン .qsf ファイル 新しい FPGA パッケージピンにマッピング
SDC 制約 coreMZ_emuMZ_constraints.sdc クロックおよびタイミング制約を更新
T80 Z80 コア、すべてのペリフェラルコントローラ(i8254、i8255、z8420、WD1793、SN76489)、および VideoController は純粋な VHDL であり、あらゆる FPGA ベンダーのツールで合成可能です。

Part 27 — ソースファイルリファレンス

FPGA/SW700/v1.3/MZ700/(メインソースツリー)

ファイル 行数 用途
coreMZ.vhd ~800 トップレベルエンティティ — ビデオのみビルド
coreMZ_SoftCPU.vhd ~1200 トップレベル — ビデオ + ソフト CPU (T80 + ZPU)
coreMZ_emuMZ.vhd 1783 トップレベル — 完全な Sharp MZ エミュレーション
coreMZ_pkg.vhd 187 パッケージ: ホストモデル定数、ユーティリティ関数
functions.vhd ~200 共有ユーティリティ関数

FPGA/SW700/v1.3/MZ700/VideoController/

ファイル 行数 用途
VideoController.vhd 5400 完全なビデオパイプライン(文字、グラフィックス、OSD、パレット)
VideoController_pkg.vhd 201 ビデオモード定数、ホストハードウェアモード定義
ChrGenRAM_DP_3208.vhd キャラクタジェネレータデュアルポート BRAM テンプレート
VideoRAM_DP_3216.vhd Video RAM デュアルポート BRAM テンプレート

FPGA/SW700/v1.3/MZ700/emuMZ/(エミュレーションコア)

ファイル 行数 用途
mctrl.vhd 689 マシン制御: CONFIG バス、レジスタデコード、リセット管理
clkgen.vhd 571 クロック生成: PLL、分周器、クロックイネーブル
arbiter.vhd 653 ウォッチドッグ付きラウンドロビンバスアービトレーション
cmt.vhd 1806 カセットテープ: PWM エンコード/デコード、APSS、データキャッシュ
keymatrix.vhd 1222 PS/2 から Sharp MZ キーボードへの変換
mz80k_hw.vhd 1416 パーソナルシリーズハードウェア (MZ-80K/C/1200/80A/700/800)
mz80b_hw.vhd 676 ビジネスシリーズハードウェア (MZ-80B/2000/2200/2500)
fdd.vhd 355 フロッピーディスクコントローラ (WD1793 エミュレーション)
iointr.vhd 325 I/O Processor 割り込み集約 FIFO
snd.vhd 369 サウンド: SN76489 + i8253 オーディオ

FPGA/SW700/v1.3/MZ700/emuMZ/(サブディレクトリ)

ディレクトリ 内容
i8254/ Intel 8254 Programmable Interval Timer VHDL
i8255/ Intel 8255 Programmable Peripheral Interface VHDL
wd1793/ WD1793 Floppy Disk Controller VHDL
z8420/ Zilog Z80 PIO VHDL
common/T80/ T80 Z80 CPU コア (T80.vhd, T80_ALU.vhd, T80_MCode.vhd, T80_Reg.vhd, T80_Pack.vhd)
mz80c/, mz80b/ マシン固有サブモジュール
mif/ メモリ初期化ファイル (.mif)

FPGA/SW700/v1.3/MZ700/softT80/

ファイル 用途
softT80.vhd T80 ソフト Z80 ラッパーモジュール
softT80_pkg.vhd T80 設定パッケージ
T80/ T80 Z80 IP コアソース(emuMZ と共有)

FPGA/SW700/v1.3/MZ700/softZPU/

ファイル 用途
softZPU.vhd ZPU Evolution ソフト CPU ラッパー
softZPU_pkg.vhd ZPU 設定パッケージ
ZPU/ ZPU Evolution コア VHDL

その他のディレクトリ

パス 内容
FPGA/SW700/v1.3/MZ700/PLL/ Altera PLL メガファンクションインスタンス
FPGA/SW700/v1.3/MZ700/SFL/ Serial Flash Loader メガファンクション(EPCS ブート ROM プログラミング)
FPGA/SW700/v1.3/MZ700/devices/ ペリフェラル IP: BRAM, SDRAM, UART, timer, interrupt, SD/MMC, RAM
FPGA/SW700/v1.3/MZ700/build/ Quartus プロジェクトファイル(バリアントごとの .qpf, .qsf, .sdc)
CPLD/ ターゲットマシンごとの CPLD VHDL ソース
schematics/SW700/ ボードリビジョンごとの KiCad 回路図 (v1.0-v1.4)
pcb/SW700/ Gerber PCB ファイル (v1.2a, v1.3, v1.3a)
tools/ ビルドユーティリティ: build_meminitfiles.sh, Python BRAM 初期化スクリプト

Part 28 — リソースとリンク

プロジェクトリンク

リソース URL
tranZPUter ソース git.eaw.app/eaw/tranZPUter
TZFS ソース git.eaw.app/eaw/TZFS
SharpMZ (MiSTer) ソース git.eaw.app/eaw/SharpMZ_MiSTer
Jenkins CI jenkins.eaw.app/job/tranZPUter-Build
Sharp MZ Emulator (tranZPUter) eaw.app/sharpmz-emulator-tzpu-700
Sharp MZ Emulator (MiSTer) eaw.app/sharpmz-emulator-de10-nano
tranZPUter SW-700 ページ eaw.app/sharpmz-700-upgrades-tranzputer-sw
TZFS ユーザーマニュアル eaw.app/tzfs-usermanual

参考ドキュメント

ドキュメント 内容
T80 CPU コア (opencores.org) Z80 命令セット実装、バスタイミング
Intel i8255A データシート Programmable Peripheral Interface 仕様
Intel i8254 データシート Programmable Interval Timer 仕様
Zilog Z8420 データシート Z80 PIO 仕様
WD1793 データシート Floppy Disk Controller コマンドセットとタイミング
SN76489 データシート Programmable Sound Generator 仕様
Intel Quartus Prime ハンドブック FPGA 合成、タイミング解析、Signal Tap
Quartus II 13.0 CPLD ハンドブック MAX7000AE フィッティング、プログラミング

Sharp MZ 技術リファレンス

機種 主な仕様
MZ-80K/C/1200 Z80 @ 2MHz, 48KB RAM, 4KB ROM, 40x25 モノクロ, カセット 1200 baud
MZ-80A Z80 @ 2MHz, 48KB RAM, 4KB ROM, 40x25 モノクロ, 改良キーボード
MZ-700 Z80 @ 3.58MHz, 64KB RAM, カラーディスプレイ, PCG オプション, 内蔵プロッタ
MZ-800 Z80 @ 3.58MHz, 64KB RAM, QD ドライブ, 拡張グラフィックス
MZ-80B Z80 @ 4MHz, 64KB RAM, 80桁表示, GRAM I/II, IPL ブート
MZ-2000 Z80 @ 4MHz, 64KB RAM, GRAM I/II/III, FDD, APSS カセット

略語リファレンス

略語 意味
APSS Automatic Program Search System
ARAM Attribute RAM(文字セルごとのカラーアトリビュート)
BRAM Block RAM(FPGA 内蔵メモリ)
CGRAM Character Generator RAM(プログラマブル文字)
CGROM Character Generator ROM(固定フォント)
CMT Cassette Magnetic Tape
CONFIG 91ビットマシン設定バス
CPLD Complex Programmable Logic Device
DRQ Data Request(WD1793 ハンドシェイク)
emuMZ Sharp MZ シリーズ FPGA エミュレーションビルドバリアント
FDC Floppy Disk Controller
FDD Floppy Disk Drive
FPGA Field-Programmable Gate Array
GRAM Graphics RAM(フレームバッファメモリ)
IOP I/O Processor (K64F ARM Cortex-M4)
IPL Initial Program Load(ブート ROM)
JTAG Joint Test Action Group(デバッグ/プログラミングインターフェース)
MZF Sharp MZ テープファイルフォーマット
OSD On-Screen Display
PCG Programmable Character Generator
PIO Parallel Input/Output (Z80 PIO Z8420)
PIT Programmable Interval Timer (i8254)
PLL Phase-Locked Loop
PPI Programmable Peripheral Interface (i8255)
PSG Programmable Sound Generator (SN76489)
SDC Synopsys Design Constraints(タイミング制約ファイル)
SFL Serial Flash Loader
SOF SRAM Object File(揮発性 JTAG プログラミング)
T80 オープンソース Z80 CPU コア (VHDL)
TZMM tranZPUter Memory Mode
TZFS tranZPUter Filing System
VRAM Video RAM(文字表示メモリ)
ZPU Zylin Processing Unit(32ビットスタック CPU)