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 エミュレーションプロジェクトのエンドツーエンドの概観 |
リポジトリ
エミュレーション対象機種
| 機種 |
シリーズ |
状態 |
主な違い |
| 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つの独立したデータパスがあります:
-
エミュレーションパス — T80 ソフト CPU が Sharp MZ ソフトウェアを実行し、アドレスデコードされたチップセレクトを介して ROM、RAM、ビデオ、ペリフェラル、カセットの読み書きを行います。これはクロックイネーブルを使用する CKMASTER クロックで、FPGA クロックドメイン内で完全に動作します。
-
IOP パス — K64F ARM プロセッサがパラレル IOP インターフェースを通じて FPGA と通信し、設定レジスタ、ROM イメージ、テープデータ、フロッピーディスクイメージ、キーボードマップを送信します。これはエミュレーションクロックに対して非同期です。
両方のパスは共有リソース(CONFIG レジスタ、CMT バッファ、キーボードマトリクス)に競合なくアクセスできます。arbiter モジュールがラウンドロビン方式で競合するリクエストをシリアライズするためです。
Part 4 — FPGA トップレベルエンティティ
トップレベルエンティティ coreMZ(coreMZ_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 信号を生成します:
- コールドリセット — パワーオンリセットカウンタ(4ビット、~16 CKMASTER サイクル)
- ウォームリセット — I/O Processor がリセットレジスタ (0x0F) に書き込み
- CPU リセット — CPU_CFG_DATA ビット 7 がセット
すべてのリセットはメタスタビリティ防止のため CKMASTER に同期されます。リセット出力はすべてのサブモジュールにファンアウトします。
Part 7 — CPU 切替メカニズム
tranZPUter SW-700 の特徴的な機能の一つは、実行時に複数の CPU を切り替えられることです。このメカニズムは I/O アドレス 0x6C の CPU_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 に書き込むことで開始されます。シーケンスは以下の通りです:
- TZFS がビット 7(リセット)をセットした新しい CPU_CFG_DATA 値を書き込みます — これによりターゲット CPU がリセット状態に保持されます。
- CPLD が 0x6C への I/O 書き込みを検出し、内部の CPU モードレジスタを更新します。
- ハード Z80 から切替える場合、CPLD がメインボード Z80 に BUSRQn をアサートします。BUSACKn を受信すると、ハード Z80 がバスをトライステートにし、FPGA が制御を引き継ぎます。
- ハード Z80 に切替える場合、FPGA がバスドライバをトライステートにし、CPLD が BUSRQn を解除します。
- TZFS(または I/O Processor)がビット 7 をクリアし、ターゲット CPU をリセットから解放します。
- 新しい CPU がリセットベクタから実行を開始します。
emuMZ モードへの移行
emuMZ モードが選択される(CPU_CFG_DATA[2]=1)と、追加の初期化が行われます:
- arbiter モジュールが起動し、T80、キーボードスキャナ、CMT インターフェース、割り込みジェネレータ、サウンドモジュール間のバスアービトレーションを制御します。
- mctrl モジュールが選択されたマシンモデルのデフォルト CONFIG をロードします。
- I/O Processor が適切なモニター ROM を FPGA ブロック RAM にロードします。
- 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) |
レンダリングパイプライン
ビデオレンダリングパイプラインは、各スキャンラインをパイプライン化されたシーケンスで処理します:
-
タイミング生成: 水平および垂直カウンタが同期、ブランキング、アクティブ表示ウィンドウを生成します。各マシンモデルには CONFIG[10:0] で選択される固有のタイミングパラメータがあります。
-
文字フェッチ: 各文字セル(幅8ピクセル)の間に、H/V 位置から VRAM アドレスが計算され、VRAM から文字コードが読み取られ、CGROM(PCG が有効な場合は CGRAM)から対応するグリフ行がフェッチされます。
-
アトリビュートフェッチ: 同じ文字セルアドレスで ARAM からカラーアトリビュートが読み取られます。アトリビュートバイトは前景色(3ビット)、背景色(3ビット)、およびオプションのブリンク/アンダーラインフラグをエンコードします。
-
グラフィックスオーバーレイ: GRAM を持つマシン(MZ-80B/2000 またはグラフィックス拡張付き MZ-700/800)の場合、Red、Green、Blue フレームバッファから対応するグラフィックスピクセル行が読み取られます。ブレンドモード(XOR、OR、AND、replace)はグラフィックス制御レジスタで選択されます。
-
パレットマッピング: 3ビットカラーインデックスがプログラマブルパレット LUT を通じて 12ビット RGB(チャンネルあたり4ビット)に拡張されます。パレットは 4096 色をサポートします。
-
VGA アップスケーリング: ネイティブ解像度(320x200 または 640x200)が、ピクセルダブリングとラインレプリケーションを使用して設定された VGA 出力モード(640x400、640x480、または 800x600)にスケーリングされます。
-
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段階で動作します:
-
PS/2 デコード: PS/2 シリアルプロトコルがスキャンコードにデコードされます。メイクコード(キー押下)とブレイクコード(キー解放)は 0xF0 プレフィクスバイトで区別されます。
-
マトリクスマッピング: 各 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 がセクタ読み取りコマンドを受信すると:
- FDD モジュールが
iointr モジュール経由で I/O Processor に割り込みを生成します。
- I/O Processor が SD カード上のディスクイメージファイルから要求されたトラック/セクタ/サイドを読み取ります。
- I/O Processor が
IOP_FDD_CSn 経由で FDD のデータバッファにセクタデータを書き込みます。
- 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 書き込みトランザクション:
- K64F がターゲットモジュールの CSn を Low にセットします。
- K64F が IOP_ADDR にレジスタオフセットを駆動します。
- K64F が IOP_DIN にデータバイトを駆動します。
- K64F が IOP_WRn を少なくとも 2 CKMASTER サイクル間 Low にアサートします。
- K64F が IOP_WRn をデアサートします。
- K64F が CSn を解放します。
代表的な IOP 読み出しトランザクション:
- K64F がターゲットモジュールの CSn を Low にセットします。
- K64F が IOP_ADDR にレジスタオフセットを駆動します。
- K64F が IOP_RDn を Low にアサートします。
- FPGA が IOP_DOUT にレジスタ値を駆動します(1 CKMASTER サイクルのレイテンシ)。
- K64F が IOP_DOUT を読み取ります。
- 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 がすぐに応答できない場合でも、複数の割り込みを順序通りにサービスすることが可能です。
割り込み処理フロー
- ペリフェラル(例: CMT)が INTRn 信号を Low にアサートします。
- iointr モジュールがソース番号をラッチし、FIFO にプッシュします。
- iointr モジュールが K64F への集約割り込み出力をアサートします。
- K64F の割り込みハンドラが IOP_INTR_CSn 経由でリーズンレジスタを読み取ります。
- リーズンコードに基づき、K64F が必要なサービスを実行します(例: 次のテープブロックのロード)。
- K64F がアクノレッジを書き込み、割り込みをクリアします。
- 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_RDn と VIDEO_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_pkg(mctrl.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 — 開発ワークフロー
編集・コンパイル・テストサイクル
一般的な開発ワークフローは以下の通りです:
- VHDL 編集 — テキストエディタまたは Quartus で関連するソースファイルを修正します。
- コンパイル —
quartus_sh --flow compile coreMZ_emuMZ を実行します(または Quartus GUI の “Start Compilation” を使用)。完全な emuMZ ビルドには最新のワークステーションで約15-25分かかります。
- プログラム — USB-Blaster を JTAG ヘッダに接続します。
quartus_pgm または Quartus Programmer で .sof ファイルをロードします。JTAG プログラミングは約10秒で完了し、揮発性です(電源オフで失われます)。
- テスト — ホストマシンの電源を入れます。FPGA が JTAG イメージからロードされ、エミュレーションが開始されます。OSD メニュー(コンパイルに含まれている場合)を使用してマシンモデルを選択し、動作を確認します。
- 反復 — 問題が見つかった場合はステップ 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 ビルドに追加するには:
- Quartus プロジェクト (
coreMZ_emuMZ.qpf) を開きます。
- Tools → Signal Tap II Logic Analyzer に移動します。
- 対象の信号を追加します(例: T80_ADDR, T80_DATA_OUT, CORE_MREQn, CLKBUS)。
- サンプルクロックを CLKBUS(CKMASTER) に設定し、サンプル深度を設定します(使用可能なブロック RAM により制限)。
- トリガ条件を定義します(例: T80_ADDR = 0x0000 でリセット後の最初の命令フェッチをキャプチャ)。
- 再コンパイル — Signal Tap がインストゥルメンテーションロジックを追加し、キャプチャバッファにブロック RAM を使用します。
- 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 — 設計の拡張
新しいペリフェラルの追加
エミュレーションに新しいペリフェラルを追加するには:
-
VHDL モジュールの作成 — 既存のモジュールパターンに従います:CLKBUS、CONFIG、IOP、バス信号を持つエンティティ、CKMASTER 上のクロックドプロセスを持つアーキテクチャ。
-
IOP チップセレクトの追加 — ペリフェラルが I/O Processor アクセスを必要とする場合、トップレベルエンティティに新しい IOP_xxx_CSn 信号を追加し、K64F のチップセレクトデコーダに接続します。
-
Arbiter への登録 — ペリフェラルがエミュレートされたバスアクセスを必要とする場合、arbiter に新しいエージェントスロットを追加します。新しい GRANT/BUSY/RESET 信号トリプレットでラウンドロビンを拡張します。
-
トップレベルへの接続 — coreMZ_emuMZ.vhd で新しいモジュールをインスタンス化し、適切な内部信号にポートを配線します。
-
QIP への追加 — Quartus がコンパイルに含めるよう、新しい VHDL ファイルを coreMZ_emuMZ.qip ファイルリストに追加します。
-
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 — リソースとリンク
プロジェクトリンク
参考ドキュメント
| ドキュメント |
内容 |
| 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) |