ZPUTA (ZPU テストアプリケーション)
ZPUTA
もともとZPUTA/zOSの開発はZPUアーキテクチャのみを対象としており、実行方式は主に2種類ありました:
- IOCPによってブートされるアプリケーションとして、
- ZPU Evoのスタートアップファームウェアとしてスタンドアロンでブート。
最近では、tranZPUterSWプロジェクトにおけるFreescale K64Fとの使用を目的として、zOS/ZPUTAがARM Cortex-M4アーキテクチャへ移植されました。K64FはCPU/SoCのアーキテクチャが固定されているため、実行方式は「スタンドアロン」のみであり、オンボードのFlashに保存されてCPUの電源投入時に起動します。
ZPUTAの目的は主にテストであり、組み込みハードウェアシステムへの内部アクセスを得て、ハードウェア機能のテストや試用のためのコードレット実行にあります。各テストは内部関数と外部アプリの両方としてビルドされていました。これは使用している開発ボードの都合上、非常に重要でした。ZPU Evo開発に使用されたCyclone V搭載DE10-Nano FPGAボードは600KB以上のRAMメモリを持つ一方、tranZPUter上のCyclone 10LPはわずか120KBであり、そのうちの一部はEvo設計でキャッシュとして使用されます。そのため後者は徹底したテストのためにSDカードと外部アプリケーションが必要です。ZPUTAのすべての機能は、プライマリ読み込みイメージ内で有効/無効を切り替えられます。
動作にあたり、ZPUTAは少なくとも1つのシリアル接続(物理またはUSB仮想)が必要であり、デバッグ出力用にできれば2つあることが望ましいです。プライマリシリアル接続にはANSI/VT100ターミナルエミュレータパッケージを接続することが推奨されます。エディタやreadlineなどのコマンドを正しく機能させるためにANSI/VT100エミュレーションが必要です。簡易シリアルターミナルでも動作しますが、アプリケーション機能は制限されます。
ZPUTAの使い方
ZPUTAに先立ち、IOCP(I/Oコントロールプログラム)と呼ばれるブートストラッププログラムを作成しました。これは最低位のハードウェアレベルで動作し、ZPUTAなどのより高度なプログラムをブートできます。IOCPはサイズに敏感であり、あらゆるメモリデバイスからブートストラップできるよう設計されており、SDカードとPetit FatFSを含めることでSDカードからのブートストラップも可能です。IOCPはもともとZPUTAのブートストラップに使用され、変更を加えた際にZPUTAカーネルをSDカードにコピーするだけで済むため開発速度の向上に貢献しましたが、最終的にはIOCPの低レベルコードをZPUTAに組み込み、IOCPなしでプライマリソフトウェアとして起動できるようになりました。IOCPはZPUTAやzOSレベルの洗練度を必要としないアプリケーションのブートのために、引き続きプロジェクト内に残っています。
数ヶ月前、tranZPUterSWプロジェクトがtranZPUterから派生し、ソフトウェアによる迅速な設計の進展を目的として誕生しました。これはPJRC.comによるTeensy 3.5開発ボード、より正確にはFreescale K64FプロセッサであるARM Cortex-M4 CPUとして実現しました。2つの異なる処理アーキテクチャに対応するためにソースコードへかなりの変更が必要でしたが、豊富なARM開発ボードの存在を考えれば、サードパーティが自身のプロジェクトでOSをより使いやすくなります。
コマンドライン
OSへの最初の接触は、CPU・バージョンなどの詳細を表示してコマンド入力のプロンプトを発行するサインオンメッセージです:

ZPUTAのコマンドラインはシェルインタープリタではなく、内蔵コマンドまたはSDカードに保存されたコマンドを発行するための基本的なテキストインターフェースです。コマンドの入力と呼び出しを補助する縮小版readline機能と履歴機能を含んでおり、GNU readlineの機能に概ね準拠しています。コマンドラインで認識されるキーは以下のとおりです:
</br>
| キー | 動作 |
|---|---|
| CTRL-A | 行頭へ移動。 |
| CTRL-B | カーソルを1つ左へ移動。 |
| CTRL-C | 現在の行を中断し、呼び出し元アプリケーションにCTRL-Cを返す。 |
| CTRL-D | シェルでは未定義、実行中のアプリケーションへ渡される。 |
| CTRL-E | 行末へ移動。 |
| CTRL-F | カーソルを1つ右へ移動。 |
| CTRL-K | 行をクリア。 |
| CTRL-N | 次の履歴コマンドを呼び出す。 |
| CTRL-P | 前の履歴コマンドを呼び出す。 |
| HOME | 行頭へ移動。 |
| END | 行末へ移動。 |
| INSERT | 未定義。 |
| DEL | カーソル下の文字を削除。 |
| BACKSPACE | カーソル左の文字を削除。 |
| PGUP | シェルでは未定義、実行中のアプリケーションへ渡される。 |
| PGDOWN | シェルでは未定義、実行中のアプリケーションへ渡される。 |
| ARROW UP | 前の履歴コマンドを呼び出す。 |
| ARROW DOWN | 次の履歴コマンドを呼び出す。 |
| ARROW RIGHT | カーソルを1つ右へ移動。 |
| ARROW LEFT | カーソルを1つ左へ移動。 |
readline機構はいくつかの内部コマンドも認識します:
| コマンド | 動作 |
|---|---|
| !<number> | <number>で識別された履歴コマンドを呼び出して実行する。 |
| hist[ory] | 履歴バッファを一覧表示する。 |
アプリケーション
ZPUTAが現在提供するアプリケーションはSDカードに保存されており、以下にまとめます。詳細情報については、アプリケーションセクション(左のナビゲーションバー)またはアプリケーションREADMEファイルを参照してください。
-
ディスクIOコマンド
コマンド パラメータ 説明 ddump [<pd#> <sect>] セクターをダンプ dinit* <pd#> [<card type>] ディスクを初期化 dstat* <pd#> ディスク状態を表示 dioctl* <pd#> ioctl(CTRL_SYNC) -
ディスクバッファコマンド
コマンド パラメータ 説明 bdump <ofs> バッファをダンプ bedit <ofs> [<data>] … バッファを編集 bfill <val> バッファを充填 blen <len> fread/fwriteコマンドの読み書き長を設定 bread <pd#> <sect> [<num>] バッファへ読み込み bwrite <pd#> <sect> [<num>] バッファをディスクへ書き込み -
ファイルシステムコマンド
コマンド パラメータ 説明 falloc <fsz> <opt> ファイルへ連続ブロックを割り当て fattr <atrr> <mask> <name> オブジェクト属性を変更 fcat <name> ファイル内容を出力 fcd <path> 現在のディレクトリを変更 fclose 開いているファイルを閉じる fconcat <src fn1> <src fn2> <dst fn> 2つのファイルを結合 fcp <src file> <dst file> ファイルをコピー fdel <obj name> オブジェクトを削除 fdir [<path>] ディレクトリを表示 fdrive <path> 現在のドライブを変更 fdump <name> [<width>] ファイル内容を16進数でダンプ fexec* <name> <ldAddr> <xAddr> <mode> ファイルをロードして実行 finit* <ld#> [<mount>] ボリュームを強制初期化 finspect <len> ファイルの一部を読んで検査 flabel <label> ボリュームラベルを設定 fload* <name> [<addr>] ファイルをメモリへロード fmkdir <dir name> ディレクトリを作成 fmkfs <ld#> <type> <au> FATボリュームを作成 fopen <mode> <file> ファイルを開く fread <len> ファイルの一部をバッファへ読み込み frename <org name> <new name> オブジェクトを名前変更 fsave <name> <addr> <len> メモリ範囲をファイルへ保存 fseek <ofs> 通常シークでファイルポインタを移動 fshowdir 現在のディレクトリを表示 fstat [<path>] ボリューム状態を表示 ftime オブジェクトのタイムスタンプを変更 ftrunc 現在のファイルポインタ位置でファイルを切り詰め fwrite <len> <val> バッファの一部をファイルへ書き込み fxtract <src> <dst> <start pos> <len> ファイルの一部を抽出 -
メモリコマンド
コマンド パラメータ 説明 mclear <start> <end> [<word>] メモリをクリア mcopy <start> <end> <dst addr> メモリをコピー mdiff <start> <end> <cmp addr> メモリを比較 mdump [<start> [<end>] [<size>]] メモリをダンプ mperf <start> <end> [<width>] [<size>] メモリ性能をテスト。
この値はCPU <-> メモリ間のものであり、実際のメモリ性能ではありません。ZPUはスタックベースのためメモリ操作にメモリを使用するため、完全なメモリ帯域幅を実現することはなく、LDIRなどの拡張命令の必要性につながります。msrch <start> <end> <value> メモリを検索。 mtest [<start> [<end>] [iter] [test mask] メモリをテスト meb <addr> <byte> […] メモリを編集(バイト) meh <addr> <h-word> […] メモリを編集(ハーフワード) mew <addr> <word> […] メモリを編集(ワード) -
ハードウェアコマンド
コマンド パラメータ 説明 hid 割り込みを無効化 hie 割り込みを有効化 hr レジスタ情報を表示 ht マイクロ秒タイマーをテスト hfd UART FIFOを無効化 hfe UART FIFOを有効化 -
性能テストコマンド
コマンド パラメータ 説明 dhry Dhrystone テスト v2.1 coremark CoreMark テスト v1.0 -
プログラム実行コマンド
コマンド パラメータ 説明 call” <addr> <addr>の関数を呼び出す jmp” <addr> <addr>のコードを実行 -
その他のコマンド
コマンド パラメータ 説明 restart アプリケーションを再起動 reset システムをリセット help [<cmd %>|<group %>] このスクリーンを表示 info 設定情報 time [<y> <m> <d> <h> <M> <s>] 現在時刻の設定/表示 -
アプリケーション
コマンド パラメータ 説明 ed <file> 基本WYSIWYGのVT100ファイルエディタ kilo <file> WYSIWYG VT100ファイルエディタ mbasic [<file>] インタラクティブなMini-Basicインタープリタ。 tbasic インタラクティブなtiny Basicインタープリタ。 -
tranZPUterコマンド
コマンド パラメータ 説明 tzload アプリセクションの完全なリストを参照。 tranZPUterメモリへのファイルのアップロード・ダウンロード、ビデオフレームの取得または新しいフレームの設定。 tzdump アプリセクションの完全なリストを参照。 tranZPUterメモリを画面にダンプ。 tzclear アプリセクションの完全なリストを参照。 tranZPUterメモリをクリア。 tzclk アプリセクションの完全なリストを参照。 Z80の代替CPU周波数を設定。 tzreset アプリセクションの完全なリストを参照。 tranZPUterをリセット。 tzio アプリセクションの完全なリストを参照。 Z80 I/Oポートの読み書きツール。 tzflupd アプリセクションの完全なリストを参照。 K64F FlashRAM更新ツール。実行中のzOS/ZPUTAカーネルを新しいバージョンに更新。
(*)の付いたすべてのコマンドはZPUTAに内蔵されています。
autoexec.bat
技術的な詳細
メモリ構成
IOCPメモリマップ
ZPUTAは通常「スタンドアロン」モードで使用されます。つまり、OSはK64Fのプライマリファームウェアとして起動します。ZPU上では、ZPUTAのより迅速な開発を支援するために、IOCPによってブートされ、新しいZPUTAイメージはFPGAを再プログラムするのではなくSDカードにコピーするだけで済みます。
使用するIOCPのメモリモデルに応じて、IOCPに現在定義されているメモリマップは以下のとおりです:

ZPUTAはIOCPによってSDカードからロードされ、ZPUTAがブートファームウェアの場合と比較してメモリ内で通常0x1000バイト先に配置されます。執筆時点では、IOCPはK64Fアーキテクチャへの移植がされていないため、ZPUでのみ使用できます。
ZPUTAメモリマップ
ZPU上で動作するZPUTAのメモリ使用マップは以下の図のとおりです。ZPUTAはブートファームウェアとして下位BRAMに常駐し、スタック/ヒープは使用可能なBRAM(またはRAM/SDRAM)の上位に置かれます。アプリケーションはビルドスクリプトで定義されたロードポイントにロードされ、通常はRAM/SDRAMの先頭またはFPGAが十分に大きい場合はBRAMの先頭になります。

K64Fプロセッサのメモリ使用マップも同様ですが、FlashRAMとRAMはZPUのように可変ではなく明確に定義されています。

アプリケーションインターフェース
ほとんどのオペレーティングシステムと同様に、ZPUTAは適切にコンパイルされたアプリケーションが使用できるAPIを提供しており、シリアル回線接続などのOS内の機能を再利用することでアプリケーションのサイズと複雑さを減らせます。
カスタムAPIメソッドセットを設計するのではなく、ZPUTA内のメソッドをアプリケーションに公開する方が合理的であると判断しました(例:xprintf)。アプリケーションがターミナルに出力を表示するためにxprintfを呼び出すと、実際にはZPUTA内のxprintfが呼び出されます。これは、ZPUTA内の固定ベクター位置にジャンプテーブルを作成することで可能になります。アプリケーションはxprintfへの呼び出しをZPUTAベクターテーブルへのジャンプに変換するマクロセットでコンパイルされます。
現時点で公開されているAPIメソッドは以下のとおりです:
| ベクター番号 | メソッド | プロトタイプ | 説明 |
|---|---|---|---|
| 000 | _break | ブレークハンドラ。 | ブレークポイント命令に遭遇したときの処理メソッド。 |
| 001 | _putchar | void putchar(char c) | 最低レベルでシリアル出力デバイスへ1文字を送信。 |
| 002 | putc | void putc (char c) | 出力ストリームへ1文字を書き込む通常メソッド。 |
| 003 | fputc | void fputc (void (*func)(unsigned char), char c) | 指定した出力デバイスまたはストリームへ1文字を書き込む。 |
| 004 | puts | void puts (const char* str) | 出力ストリームへ文字列を送出。 |
| 005 | gets | int gets (char* buff, int len) | 入力ストリームから文字列を取得。 |
| 006 | fgets | int fgets (unsigned char (func)(void), char buff, int len) | 指定した入力デバイスまたはストリームから文字列を取得。 |
| 007 | fputs | void fputs (void (func)(unsigned char), const char str) | 指定した出力デバイスまたはストリームへ文字列を送出。 |
| 008 | xatoi | int xatoi (char** str, long* res) | 文字列をlongに変換。文字列は任意のフォーマットまたは基数が使用可能。 |
| 009 | uxatoi | int uxatoi(char **, uint32_t *) | 文字列を符号なし32ビットに変換。文字列は任意のフォーマットまたは基数が使用可能。 |
| 010 | printf | void printf (const char* fmt, …) | 書式付き文字列を出力ストリームへ出力。浮動小数点は非サポート。 |
| 011 | vprintf | void vprintf (const char*, va_list ) | 可変引数書式付き文字列を出力ストリームへ出力。浮動小数点は非サポート。 |
| 012 | sprintf | void sprintf (char* buff, const char* fmt, …) | 書式付き文字列を文字列バッファへ出力。浮動小数点は非サポート。 |
| 013 | fprintf | void fprintf (void (func)(unsigned char), const char fmt, …) | 書式付き文字列を指定した出力デバイスまたはストリームへ出力。 |
| 014 | getScreenWidth | uint8_t getScreenWidth(void) | 現在のスクリーン幅を返す。zOSがユーザーOSとして動作する場合に主に使用され、スクリーン幅は動的ですが、組み込み用途では固定の定数を返します。 |
| 015 | getKey | int8_t getKey(uint8_t mode) | キーボード(シリアルまたは物理)から最低レベルで1文字を取得。mode = 0 - ホスト未マップキーボード非ブロッキング、1 - ホスト未マップキーボードブロッキング、2 - ANSI非ブロッキング、3 - ANSIブロッキング。未マップはシリアルキーボードでANSIを返すか、Sharp MZ-700キースキャンコードなどのホストハードウェア値を返します。 |
| 016 | crc32_init | unsigned int crc32_init(void) | CRC32ジェネレーターを初期化。 |
| 017 | crc32_addword | unsigned int crc32_addword(unsigned int crc_in, unsigned int word) | 生成中のCRC32にワードを追加し、追加後の現在のCRC32値を返す。 |
| 018 | get_dword | unsigned int get_dword(void) | シリアル入力デバイスから符号なし32ビットワード(バイナリ形式、ビッグエンディアン)を取得。 |
| 019 | rtcSet | uint8_t rtcSet(RTC *time) | オンボードのリアルタイムクロックを指定した日時に設定。 |
| 020 | rtcGet | void rtcGet(RTC *time) | オンボードのリアルタイムクロックから現在の日時を取得。 |
| 021 | f_open | FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode) | ファイルを開くまたは作成する |
| 022 | f_close | FRESULT f_close (FIL* fp) | 開いているファイルオブジェクトを閉じる |
| 023 | f_read | FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br) | ファイルからデータを読み込む |
| 024 | f_write | FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw) | ファイルへデータを書き込む |
| 025 | f_lseek | FRESULT f_lseek (FIL* fp, FSIZE_t ofs) | ファイルオブジェクトのファイルポインタを移動する |
| 026 | f_truncate | FRESULT f_truncate (FIL* fp) | ファイルを切り詰める |
| 027 | f_sync | FRESULT f_sync (FIL* fp) | 書き込みファイルのキャッシュデータをフラッシュする |
| 028 | f_opendir | FRESULT f_opendir (DIR* dp, const TCHAR* path) | ディレクトリを開く |
| 029 | f_closedir | FRESULT f_closedir (DIR* dp) | 開いているディレクトリを閉じる |
| 030 | f_readdir | FRESULT f_readdir (DIR* dp, FILINFO* fno) | ディレクトリ項目を読み込む |
| 031 | f_mkdir | FRESULT f_mkdir (const TCHAR* path) | サブディレクトリを作成する |
| 032 | f_unlink | FRESULT f_unlink (const TCHAR* path) | 既存のファイルまたはディレクトリを削除する |
| 033 | f_rename | FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new) | ファイルまたはディレクトリの名前変更・移動 |
| 034 | f_stat | FRESULT f_stat (const TCHAR* path, FILINFO* fno) | ファイルの状態を取得する |
| 035 | f_chmod | FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask) | ファイル/ディレクトリの属性を変更する |
| 036 | f_utime | FRESULT f_utime (const TCHAR* path, const FILINFO* fno) | ファイル/ディレクトリのタイムスタンプを変更する |
| 037 | f_chdir | FRESULT f_chdir (const TCHAR* path) | 現在のディレクトリを変更する |
| 038 | f_chdrive | FRESULT f_chdrive (const TCHAR* path) | 現在のドライブを変更する |
| 039 | f_getcwd | FRESULT f_getcwd (TCHAR* buff, UINT len) | 現在のディレクトリを取得する |
| 040 | f_getfree | FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs) | ドライブ上の空きクラスター数を取得する |
| 041 | f_getlabel | FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn) | ボリュームラベルを取得する |
| 042 | f_setlabel | FRESULT f_setlabel (const TCHAR* label) | ボリュームラベルを設定する |
| 043 | f_expand | FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt) | ファイルへ連続ブロックを割り当てる |
| 044 | f_mount | FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt) | 論理ドライブをマウント/アンマウントする |
| 045 | f_mkfs | FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len) | FATボリュームを作成する |
| 046 | f_putc | FRESULT f_putc (TCHAR c, FIL* fp) | ファイルへ1文字を書き込む |
| 047 | f_gets | FRESULT f_gets (TCHAR* buff, int len, FIL* fp) | ファイルから文字列を取得する |
| 048 | disk_read | DRESULT disk_read ( BYTE drv, BYTE *buff, DWORD sector, UINT count ) | SDカードから完全または部分的なセクターを直接読み込む |
| 049 | disk_write | DRESULT disk_write ( BYTE drv, const BYTE *buff, DWORD sector, UINT count ) | SDカードへ完全または部分的なセクターを直接書き込む |
| 050 | disk_ioctl | DRESULT disk_ioctl ( BYTE drv, BYTE ctrl, void *buff ) | SDカードへ直接制御コマンドを発行する。 |
| 051 | getStrParam | char *getStrParam(char **ptr) | 文字列パラメータリスト内で次の文字列パラメータへのポインタを取得。文字列パラメータリストへのポインタは次の+1パラメータを指すよう更新される。 |
| 052 | getUintParam | uint32_t getUintParam(char **ptr) | 文字列パラメータリストから次の32ビット符号なし整数を取得。文字列パラメータリストへのポインタは次の+1パラメータを指すよう更新される。 |
| 053 | set_serial_output | void set_serial_output(uint8_t c) | 2つ以上のシリアルポートを持つボードで、指定デバイスをプライマリ出力ストリームデバイスとして割り当てる。 |
| 054 | printFSCode | void printFSCode(FRESULT result) | Fat FSの呼び出しから返された結果コードをテキストとして表示する。 |
| 055 | malloc | void *malloc(size_t __size) | ヒープ上にメモリブロックを割り当てる。 |
| 056 | realloc | void *realloc(void *__ptr, size_t __size) | メモリブロックのサイズを変更し、新しいブロックが必要な場合はデータをコピーする。 |
| 057 | calloc | void *calloc(size_t __size) | ヒープ上にゼロ初期化されたメモリブロックを割り当てる。 |
| 058 | free | void free(void *__ptr) | メモリブロックをヒープへ返却する。 |
| 059 | setupZ80Pins | void setupZ80Pins(uint8_t, volatile uint32_t *) | Z80の機能に従ってすべてのピンを初期化する。ハードウェアから論理へのマッピングテーブルをセットアップ。 |
| 060 | resetZ80 | void resetZ80(uint8_t) | Z80の物理RESETを実行する。 |
| 061 | reqZ80Bus | uint8_t reqZ80Bus(uint32_t) | Z80バスの制御を要求する。 |
| 062 | reqMainboardBus | uint8_t reqMainboardBus(uint32_t) | ホストマザーボードリソースへのアクセスのためにZ80バスの制御を要求する。 |
| 063 | reqTranZPUterBus | uint8_t reqTranZPUterBus(uint32_t, enum TARGETS) | tranZPUterリソースへのアクセスのためにZ80バスの制御を要求する。 |
| 064 | setupSignalsForZ80Access | void setupSignalsForZ80Access(enum BUS_DIRECTION) | Z80アクセスの方向(読み取りまたは書き込み)を設定する。 |
| 065 | releaseZ80 | void releaseZ80(void) | 以前に付与されたZ80バスを解放する。 |
| 066 | writeZ80Memory | uint8_t writeZ80Memory(uint32_t, uint8_t, enum TARGETS) | Z80ホストメモリへ1バイトを書き込む。 |
| 067 | readZ80Memory | uint8_t readZ80Memory(uint32_t) | Z80ホストメモリから1バイトを読み込む。 |
| 068 | writeZ80IO | uint8_t writeZ80IO(uint32_t, uint8_t, enum TARGETS) | Z80 I/O領域へ1バイトを書き込む。 |
| 069 | readZ80IO | uint8_t readZ80IO(uint32_t, enum TARGETS) | Z80 I/O領域から1バイトを読み込む。 |
| 070 | refreshZ80 | void refreshZ80(void) | 次のRASリフレッシュを実行する(ホストDRAMのリフレッシュ用)。 |
| 071 | refreshZ80AllRows | void refreshZ80AllRows(void) | ホストDRAMの全行を完全にリフレッシュする。 |
| 072 | setCtrlLatch | void setCtrlLatch(uint8_t) | 異なるメモリプロファイルを適用するためにメモリモードラッチを設定する。 |
| 073 | setZ80CPUFrequency | uint32_t setZ80CPUFrequency(float, uint8_t) | Z80 CPUの周波数(1Hzから24MHz)を設定する。 |
| 074 | copyFromZ80 | uint8_t copyFromZ80(uint8_t *, uint32_t, uint32_t, enum TARGETS) | Z80ホストからK64F RAMへメモリブロックをコピーする。 |
| 075 | copyToZ80 | int8_t copyToZ80(uint32_t, uint8_t *, uint32_t, enum TARGETS) | K64F RAM/FlashRAMからZ80ホストメモリへメモリブロックをコピーする。 |
| 076 | fillZ80Memory | void fillZ80Memory(uint32_t, uint32_t, uint8_t, enum TARGETS) | ホストにあるメモリブロックを指定した値で埋める。 |
| 077 | captureVideoFrame | void captureVideoFrame(enum VIDEO_FRAMES, uint8_t) | 画面ビデオバッファの内容を取得してローカルRAMに保存する。 |
| 078 | refreshVideoFrame | void refreshVideoFrame(enum VIDEO_FRAMES, uint8_t, uint8_t) | ローカルRAMベースのビデオバッファからホストビデオバッファへリフレッシュまたは書き込みを行う。 |
| 079 | loadVideoFrameBuffer | FRESULT loadVideoFrameBuffer(char *, enum VIDEO_FRAMES) | ファイルの内容でローカルRAMベースのビデオバッファをロードする。 |
| 080 | saveVideoFrameBuffer | FRESULT saveVideoFrameBuffer(char *, enum VIDEO_FRAMES) | ローカルRAMベースのビデオバッファをファイルへ保存する。 |
| 081 | getVideoFrame | char *getVideoFrame(enum VIDEO_FRAMES) | ローカルRAMベースのビデオフレームのアドレスを取得する。 |
| 082 | getAttributeFrame | char *getAttributeFrame(enum VIDEO_FRAMES) | ローカルRAMベースのビデオ属性フレームのアドレスを取得する。 |
| 083 | loadZ80Memory | FRESULT loadZ80Memory(const char *, uint32_t, uint32_t, uint32_t, uint32_t *, enum TARGETS, uint8_t) | ファイルの内容からZ80ホストメモリをロードする。 |
| 084 | loadMZFZ80Memory | FRESULT loadMZFZ80Memory(const char *, uint32_t, uint32_t *, enum TARGETS, uint8_t) | Sharp MZF形式のファイル内容をZ80メモリにロードする。 |
| 085 | saveZ80Memory | FRESULT saveZ80Memory(const char *, uint32_t, uint32_t, t_svcDirEnt *, enum TARGETS) | Z80ホストメモリの内容をファイルへ保存する。 |
| 086 | memoryDumpZ80 | int memoryDumpZ80(uint32_t, uint32_t, uint32_t, uint8_t, enum TARGETS) | Z80ホストメモリの内容を現在の出力デバイスへ書式付き16進数形式でダンプする。 |
| 087 | isZ80Reset | uint8_t isZ80Reset(void) | 外部ホストRESETが発生したかどうかをテストする。 |
| 088 | isZ80MemorySwapped | uint8_t isZ80MemorySwapped(void) | Sharp MZ-80Aのテスト:0000からのメモリがC000へスワップされたかを確認する。 |
| 089 | getZ80IO | uint8_t getZ80IO(uint8_t *) | 最後のポーリング以降にZ80 I/Oイベントが発生した場合、そのイベントを取得するメソッド。tranZPUter SW ボード v2.x以降ではZ80 I/Oイベントのトラップが不要になったため、このメソッドは非推奨です。 |
| 090 | clearZ80Reset | void clearZ80Reset(void) | 外部RESETイベントをクリアするメソッド。 |
| 091 | hardResetTranZPUter | void hardResetTranZPUter(void) | tranZPUterボードの強制ハードリセットを実行するメソッド。 |
| 092 | convertSharpFilenameToAscii | void convertSharpFilenameToAscii(char *, char *, uint8_t) | Sharp MZFファイル名をASCII形式に変換するメソッド。 |
上記のメソッドに加え、アプリケーションに公開されて自由に使用できる2つのグローバルパラメータブロックがあります:
変数 G でアクセスするグローバルパラメータブロック:
// アプリケーションからアクセス可能なグローバルパラメータ。
typedef struct {
uint8_t fileInUse; // file[0]が使用中かどうかを示すフラグ。
FIL File[MAX_FILE_HANDLE]; // 最大オープンファイルオブジェクト数
FATFS FatFs[FF_VOLUMES]; // 各論理ドライブのファイルシステムオブジェクト
BYTE Buff[512]; // ワーキングディスクバッファ
DWORD Sector; // 読み込むセクター
#if defined __K64F__
uint32_t volatile *millis; // K64Fミリ秒ティックへのポインタ
#endif
#if defined __TRANZPUTER__
int ctrlThreadId; // tranZPUterコントロールスレッドのID。
uint8_t ctrlThreadBusy; // コントロールスレッドを邪魔できないときを示すフラグ。
#endif
} GLOBALS;
プログラム内での使用例:
printf("Sector:%d\n", G->Sector);
変数 cfgSoC でアクセスする設定ブロック:
// 設定値。
typedef struct
{
uint32_t addrInsnBRAM;
uint32_t sizeInsnBRAM;
uint32_t addrBRAM;
uint32_t sizeBRAM;
uint32_t addrRAM;
uint32_t sizeRAM;
uint32_t addrSDRAM;
uint32_t sizeSDRAM;
uint32_t addrWBSDRAM;
uint32_t sizeWBSDRAM;
uint32_t resetVector;
uint32_t cpuMemBaseAddr;
uint32_t stackStartAddr;
uint16_t zpuId;
uint32_t sysFreq;
uint32_t memFreq;
uint32_t wbMemFreq;
uint8_t implSoCCFG;
uint8_t implWB;
uint8_t implWBSDRAM;
uint8_t implWBI2C;
uint8_t implInsnBRAM;
uint8_t implBRAM;
uint8_t implRAM;
uint8_t implSDRAM;
uint8_t implIOCTL;
uint8_t implPS2;
uint8_t implSPI;
uint8_t implSD;
uint8_t sdCardNo;
uint8_t implIntrCtl;
uint8_t intrChannels;
uint8_t implTimer1;
uint8_t timer1No;
} SOC_CONFIG;
プログラム内での使用例:
if(cfgSoC->implSDRAM) { ... }
そのプロトタイプは以下のとおりです:
uint32_t app(uint32_t param1, uint32_t param2)
アプリケーションからzOSへの戻りコードは32ビット符号なし整数です。0はアプリケーションが正常に実行されたことを意味し、0xFFFFFFFFは失敗を示し、それ以外の値はより詳細な失敗情報、参照値、または将来のコマンドによる条件処理のために使用されます。
app()の標準テンプレートは以下のとおりです:
// zOS/ZPUTAアプリケーションのメインエントリポイントおよび開始点。2つのパラメータと32ビットの戻りコードのみに対応しており、
// 追加パラメータはapp()呼び出し前にスタックへ追加するようappcrt0.sスタートアップコードを変更することで追加できます。
//
// ZPUの戻りコードはCコンパイラによって_memregに保存され、appcrt0.sでzOS/ZPUTAへの返却前に_memregに転送されます。
// K64F ARMプロセッサは標準レジスタ渡し規約を使用し、戻りコードはR0に格納されます。
//
uint32_t app(uint32_t param1, uint32_t param2)
{
// 初期化。
//
char *ptr = (char *)param1;
long startAddr;
long endAddr;
long bitWidth;
long xferSize;
#if defined __K64F__
uint32_t perfTime;
#endif
uint32_t retCode = 0;
if (!xatoi(&ptr, &startAddr))
{
printf("Illegal <start addr> value.\n");
retCode = 0xFFFFFFFF;
} else if (!xatoi(&ptr, &endAddr))
{
printf("Illegal <end addr> value.\n");
retCode = 0xFFFFFFFF;
} else
{
xatoi(&ptr, &bitWidth);
if(bitWidth != 8 && bitWidth != 16 && bitWidth != 32)
{
bitWidth = 32;
}
if(!xatoi(&ptr, &xferSize))
{
xferSize = 10;
}
}
... application logic
return(retCode);
}
ソフトウェアビルド
パス
読みやすさのため、この章では以下の短縮名が対応するパスを指します。
| 短縮名 | パス | 説明 |
|---|---|---|
| [<ABS PATH>] | このリポジトリをシステム上に展開したパス。 | |
| <apps> | [<ABS PATH>]/zsoft/apps | アプリケーションディレクトリ。すべてのzOS/ZPUTAアプリケーションとそのMakefileがここに保存されます。 |
| <build> | [<ABS PATH>]/zsoft/build | コンパイルされたソフトウェアのターゲット出力ディレクトリ。例:<z-build>/SDにはSDカードに書き込むすべてのファイルが含まれます。 |
| <common> | [<ABS PATH>]/zsoft/common | ライブラリにアセンブルされない共通C/C++メソッド。 |
| <libraries> | [<ABS PATH>]/zsoft/libraries | C/C++ライブラリ。通常はC/C++インストールの一部ですが、組み込み作業、特にZPU上では個別に作成する必要があります。 |
| <teensy3> | [<ABS PATH>]/zsoft/teensy3 | K64FベースのTeensy 3.5ソフトウェア。一部はzOSのK64Fバージョンで使用されます。豊富なライブラリを持ち、K64Fプログラムに簡単に追加できます。 |
| <include> | [<ABS PATH>]/zsoft/include | 共通インクルードヘッダファイル。 |
| <startup> | [<ABS PATH>]/zsoft/startup | 組み込みプロセッサのスタートアップファイル(主にアセンブラ)。テンプレートとマクロを使用して正しいターゲットメモリモデルのスタートアップコードを作成します。 |
| <iocp> | [<ABS PATH>]/zsoft/iocp | IO Control Program。ZPU上でアプリケーションをブートストラップするための初期ブートローダ。 |
| <zOS> | [<ABS PATH>]/zsoft/zOS | zOSのソースコード。異なるターゲットCPU用にパラメータ化されています。 |
| <zputa> | [<ABS PATH>]/zsoft/zputa | ZPUTAのソースコード。異なるターゲットCPU用にパラメータ化されています。 |
| <rtl> | [<ABS PATH>]/zsoft/rtl | レジスタ転送レベルファイル。ZPUターゲットプロジェクトのビルド時に必要な、生成されたメモリ定義および初期化ファイル。 |
| <docs> | [<ABS PATH>]/zsoft/docs | ソフトウェアに関連するすべてのドキュメント。 |
| <tools> | [<ABS PATH>]/zsoft/tools | コンパイルとターゲットファイル作成を支援するツール。 |
ツール
すべての開発はLinux(具体的にはDebian/Ubuntu)上で行われています。標準のLinuxビルドチェーンに加え、以下のソフトウェアが必要です。
| ZPU GCC ToolChain | ZPU開発用のGCCツールチェーン。/optまたはそれに類した共通領域にインストールしてください。 |
| Arduino | Arduinoの開発環境。zOSのK64Fバージョンに広大なArduinoライブラリから機能を追加する場合を除き、実際には不要です。参照用途が主です。 |
| Teensyduino | ArduinoレベルでTeensy3.5ボードを扱うためのTeensy3 Arduino拡張。実際には不要で、参照用途が主です。 |
Teensy3.5/K64F用のARM互換ツールチェーンはリポジトリ内のビルドツリーに保存されています。
ビルドツリー
ソフトウェアは以下のツリー/フォルダに構成されています:
| フォルダ | ソースファイル | 説明 |
|---|---|---|
| apps | zOS/ZPUTAアプリケーションのアプレットツリー。zOS/ZPUTA上で動作するスタンドアロンのディスクベースアプレットです。 zOS/ZPUTA用のすべてのアプレットはこのフォルダに保存されています。 |
|
| build | SDカードへ直接コピーするのに適したビルドツリー出力。 選択された初期ブートローダおよび/またはアプリケーションは、devices/sysbus/BRAMフォルダ内のBRAMへのプリロード用VHDLファイルに直接コンパイルされます。 |
|
| common | Elm ChanのFat FileSystemなどの共通Cモジュール。 | |
| docs | このプロジェクトに関連するすべてのドキュメント。 | |
| libraries | コードライブラリ。まもなくummlibcとFreeRTOSが追加されます。 | |
| rtl | レジスタ転送レベルのテンプレートと生成ファイル。ZPUで使用されるBRAMベースのRAM/ROMのプリロードされたVHDL定義を含みます。 | |
| teensy3 | K64Fプロセッサターゲットのビルドに必要なTeensy 3.5ファイル。 | |
| include | CインクルードヘッダファイL。 | |
| iocp | ZPUの初期化のための小さなブートローダ/モニターアプリケーション。設定に応じてSDカードまたはシリアルラインからアプリケーションをブートするほか、メモリ検査などの基本ツールも提供します。 | |
| startup | ZPUアプリケーション生成のためのアセンブラとリンカファイル。GCCがバイナリイメージをどのように作成・リンクするかを定義するために重要であり、ハードウェアに実装されていないZPU命令のマイクロコードも提供します。 | |
| tools | バイナリイメージをVHDL初期化データに変換するための小ツール。 | |
| zputa | ZPU Test Application。ZPUとSoCコンポーネントをテストするためのアプリケーション。VHDLを介してBRAMにプリロードする単一イメージとして、またはIOCPブートローダによってSDカードからロードされるスタンドアロンアプリケーションとしてビルドできます。提供するサービスはメモリの制約に応じて、組み込みまたはSDカード上のアプレットとして利用可能です。 | |
| zOS | z-Operating System。ZPUTAから派生した軽量OSであり、ZPUまたはK64Fプロジェクト内でアプリケーションビルドとランタイム制御の両方のフレームワークを提供することを目的としています。ディスクベースのサービス、共通ハードウェアアクセスAPIを提供し、この環境向けにビルドされたアプリケーションの実行と管理のための追加機能を持ちます。アプリケーションは自律的に、またはシリアルベースのVT100コンソールを通じてインタラクティブに起動できます。 | |
| build.sh | IOCP、zOS、ZPUTAおよびアプリを指定の設計向けにビルドするUnixシェルスクリプト。![]() |
Build.sh
ZPUTAは’build.sh’スクリプトを使用してビルドします。このスクリプトはMakefileシステムを多数のフラグやオプションとともにカプセル化します。スクリプトの概要は以下のとおりです:
NAME
build.sh - ZPU/K64FプログラムまたはOSをビルドするシェルスクリプト。
SYNOPSIS
build.sh [-CIOoMBAsTZdxh]
DESCRIPTION
OPTIONS
-C <CPU> = Small, Medium, Flex, Evo, EvoMin, K64F - デフォルトはEvo。
-I <iocp ver> = 0 - Full, 1 - Medium, 2 - Minimum, 3 - Tiny (ブートストラップのみ)
-O <os> = zputa, zos
-o <os ver> = 0 - スタンドアロン, 1 - IOCPブートローダ付きアプリ,
2 - Tiny IOCPブートローダ付きアプリ, 3 - RAM内のアプリ
-M <size> = ブートROM/BRAMの最大サイズ(スタック設定に必要)。
-B <addr> = <os>のベースアドレス。デフォルト -o == 0 : 0x00000 else 0x01000
-A <addr> = <os>のアプリアドレス。デフォルト 0x0C000
-N <size> = ヒープの必要サイズ
-n <size> = アプリケーションヒープの必要サイズ
-S <size> = スタックの必要サイズ
-s <size> = アプリケーションスタックの必要サイズ
-a <size> = アプリの最大サイズ。デフォルトは(BRAM SIZE - App Start Address - Stack Size)
アプリ開始がBRAM内にある場合、それ以外はデフォルト 0x10000。
-T = tranZPUter専用ビルド。初期化とセットアップコードを追加します。
-Z = Sharp MZシリーズ ZPUビルド。zOSがSharp MZハードウェア上のホストOSとして動作します。
-d = デバッグモード。
-x = シェルトレースモード。
-h = このヘルプ画面。
EXAMPLES
build.sh -O zputa -B 0x00000 -A 0x50000
EXIT STATUS
0 コマンドが正常に実行された
>0 エラーが発生した。
適切なデフォルト値がスクリプトに設定されており、上書き可能なフラグは以下のとおりです。
| フラグ | 説明 |
|---|---|
| -C <CPU> | 完成イメージのターゲットCPU。各ZPUは異なる設定を持つため、基盤となるMakeのスタートアップコードと設定の選択を誘導するためにこのフラグが必要です。ARM K64Fの追加により、このフラグの意味がさらに明確になります。 選択肢: Small - ほとんどの命令がマイクロコードで実装された絶対最小限のZPUハードウェア設計。 Medium - ハードウェアを多く使用してより高い性能を持つ中間的なZPU設計。大多数の命令はハードウェアに組み込まれています。 Flex - 多くの拡張機能を持つZPUスモールベースの設計。大多数の命令がハードウェアに組み込まれています。 Evo - ZPUの最新進化版。すべての命令がハードウェアに組み込まれており、拡張命令の追加フレームワークと性能向上のための2段階キャッシュを持ちます。 K64F - FreescaleのARM Cortex-M4ベースのプロセッサ。 デフォルトはEvo。 |
| -I <iocp ver> | ビルドのメモリモデルを設定します。メモリモデルは上記に説明されています。 選択肢: 0 - Full 1 - Medium 2 - Minimum 3 - Tiny(ブートストラップのみ)。 デフォルトは3。 |
| -O <os> | ターゲットオペレーティングシステムを設定します。 選択肢: zputa - K64F上でも動作するZPU Test Application。 zos - zOSオペレーティングシステム。 デフォルトはありません。OSをビルドする場合はこのフラグが必須です。 |
| -o <os ver> | オペレーティングシステムのターゲットモデルを設定します。 選択肢: 0 - スタンドアロン:OSがスタートアップファームウェアとなります。 1 - IOCPブートローダ付きアプリ:OSはIOCPによってSDカードからブートされ、IOCPはメモリに常駐します。 2 - Tiny IOCPブートローダ付きアプリ:OSは可能な限り小さいIOCPによってSDカードからブートされ、IOCPはメモリに常駐します。 3 - RAM内のアプリ:OSは外部(FPGAの外)のRAM(スタティックまたはダイナミック)にロードされるよう設定され、IOCPはBRAMにメモリ常駐します。 デフォルトは2。 このフラグはK64Fターゲットでは意味を持ちません。 |
| -M <size> | ブートROM/BRAMの最大サイズを指定します(スタック設定に必要)。 このフラグはK64Fターゲットでは意味を持ちません。 |
| -B <addr> | <os>のベースアドレス。 デフォルト:-o == 0の場合は0x00000、それ以外は0x01000。 このフラグはK64Fターゲットでは意味を持ちません。 |
| -A <addr> | 指定された<os>のアプリ開始/ロードアドレス。 デフォルト:ZPUは0x0C000、K64Fは0x1FFF0000。 |
| -N <size> | <os>ヒープの必要サイズ。OSとアプリケーションのヒープは現在分離しています。RTOSがzOSに統合される場合は変更されます。 |
| -n <size> | アプリケーションヒープの必要サイズ。アプリケーションは個別のヒープが割り当てられ、アプリケーションによって管理されます。 |
| -S <size> | スタックの必要サイズ。通常、<os>がスタックを管理し、アプリケーションにも使用されます。アプリケーションが危険と見なされる場合は、ローカルスタックを割り当てるべきです。 |
| -s <size> | アプリケーションスタックの必要サイズ。通常、アプリケーションは<os>スタックを共有するため、これは不要です。アプリケーションが危険な場合は、この値を設定してローカルスタックを割り当ててください。 |
| -a <size> | アプリケーションの最大サイズ。 デフォルト:ZPUでアプリ開始がBRAM内にある場合は(BRAM SIZE - App Start Address - Stack Size)、それ以外は0x10000。K64Fでは0x20030000 - Stack Size - Heap Size - 0x4000。アプリ開始がBRAM内にある場合以外はデフォルトで0x10000。 |
| -T | tranZPUter専用ビルド。初期化とセットアップコードを追加します。tranZPUterボード向けの組み込みOSとしてビルドします。 |
| -Z | Sharp MZシリーズのZPUビルド。zOSがZPU/NIOSIIをホストプロセッサとして実行するSharp MZシリーズコンピュータ上のホストOSとして動作します。 |
| -d | デバッグモード。スクリプトが行う状態と判断についてより詳細な出力を有効にします。 |
| -x | シェルトレースモード。シェル実行の行ごとの非常に低レベルなトレース。デバッグ中にのみ使用します。 |
| -h | このヘルプ画面。 |
FreescaleのK64Fプロセッサ上で動作する標準的なzOSをビルドするには、以下のコマンドを発行します:
<ABS PATH>/build.sh -C K64F -O zos -B 0x00000000 -N 0x00002000 -S 0x00001000 -A 0x1FFF0000 -n 0x00020000 -s 0x00000000
このコマンドは以下を指定しています:
- ターゲットCPUはK64Fプロセッサ (-C K64F)、
- ターゲットOSはzOS (-O zos)、
- 生成されるファームウェアのベースまたは開始アドレスは0x00000000 (-B 0x00000000)、
- zOSのヒープサイズは0x00002000バイト (-N 0x00002000)、
- zOSのスタックサイズは0x000010000バイト (-S 0x000010000)、
- アプリケーションの開始アドレスはRAMのベース0x1FFF0000 (-A 0x1FFF0000)、
- アプリケーションのヒープサイズは0x00020000 (-n 0x00020000)、
- アプリケーションにはローカルスタックなし (-s 0x00000000)。
完了すると、出力は2か所に保存されます:
<zOS>/main.(hex | bin | srec) - K64F FlashRAMの0x00000000に直接フラッシュ可能な3つの標準形式によるメインzOSファームウェア。<br>
<build>/SD - FAT32フォーマットされたSDカードに直接コピーできるアプリケーション(ZPUプロセッサとIOCPを使用する場合はカーネルも含む)。<br>
Jenkinsを使ってビルドを自動化することもできますが、シンプルにすぐビルドを開始するには、build.shと階層的なMakefileシステムを使って、ここにある基本的な手順に従ってください。
- ZPU GCC ToolChainをダウンロードしてインストールします。/optまたはそれに類した共通領域にインストールしてください。
- 環境変数のパスを設定します。
export PATH=$PATH:/opt/zpu/bin - zSoftリポジトリをクローンします。
- <zputa>/src/zputa.hファイルを編集し、ZPUTAコアイメージにビルドする機能を選択します(デフォルトではすべての機能がアプレットとしてビルドされますが、ZPUTAコアイメージに組み込まれている場合は無視されます)。BUILTIN_<utility>を’1’に設定すると機能が選択され、’0’に設定すると組み込まれません。
- 使用するメモリマップと、ZPUTAをアプリケーションとして使用するかブートローダとして使用するかを決定します(自分のアプリケーションにとっても同様の選択です)。上の表のbuild.shのオプションを参照してください。決定したら、ビルドコマンドを発行します。
cd [ABS PATH] # このビルドでは、Tiny IOCPブートローダを選択し、ZPUTAをTiny IOCPブートローダ付きアプリとしてビルドします。 # ZPUTAのベースアドレスは0x1000、アプレットのロードと実行アドレスは0xC000です。 ./build.sh -I 3 -O zputa -o 2 -B 0x1000 -A 0xC000 # ビルドコマンドはIOCPブートローダを含むVHDL BRAMイメージを自動的に作成します。 # そのため、新しいブートローダを有効にするにはZPU Evo SOFビットストリームをビルドして # FPGAにアップロードする必要があります。 - システムにSDカードを挿入してFAT32フォーマットし、ファイルをコピーします。
cd build/SD cp -r * <SDカードへの絶対パス、例:/media/psmart/ZPU> # SDカードを取り出し、FPGAの開発ボード上のSDカードリーダーに挿入します。
クレジット
サードパーティの設計を使用またはベースにしたコンポーネントについては、ヘッダーに元の著者の著作権表示を記載するか、適切なクレジットを付与しています。私の知識と調査の範囲では、すべてのサードパーティソフトウェアはオープンソースであり自由に使用可能です。ライセンス制限のあるコンポーネントが見つかった場合は、このリポジトリから削除し、適切なリンクや設定を提供します。
ライセンス
オリジナルのZPUはFree BSDライセンスを使用しており、Evoも同様にFreeBSDの下でリリースされています。私が作成したSoCコンポーネントおよびその他の開発は現在GPLでライセンスされています。サードパーティのコンポーネントは元の著作権表示を維持します。
FreeBSDライセンス
ソース形式およびバイナリ形式での再配布および使用は、変更の有無にかかわらず、以下の条件を満たす場合に許可されます:
- ソースコードの再配布は、上記の著作権表示、この条件リスト、および以下の免責事項を保持しなければなりません。
- バイナリ形式での再配布は、上記の著作権表示、この条件リスト、および以下の免責事項を、配布物に付属するドキュメントおよび/またはその他の資料に再現しなければなりません。
本ソフトウェアは「現状のまま」提供され、商品性および特定目的への適合性の黙示的保証を含む(ただしこれに限らない)明示または黙示のいかなる保証も否認します。いかなる場合においても、ZPUプロジェクトまたはその貢献者は、直接的、間接的、付随的、特別、懲罰的、または結果的損害(代替品またはサービスの調達、使用・データ・利益の損失、事業の中断を含むがこれに限らない)について、たとえそのような損害の可能性について告知されていたとしても、責任を負いません。これは、契約、厳格責任、不法行為(過失またはその他を含む)のいかなる責任理論に基づく場合でも同様です。
本ソフトウェアおよびドキュメントに含まれる見解と結論は著者のものであり、明示または黙示を問わず、このプロジェクトの公式ポリシーを代表するものと解釈されるべきではありません。
GNU一般公衆ライセンス v3
このプロジェクト内でGPL v3として標記されたソースファイルおよびバイナリファイルはフリーソフトウェアです:Free Software Foundationが公開するGNU一般公衆ライセンスのバージョン3、またはそれ以降のバージョンの条件の下で、再配布および/または変更することができます。
ソースファイルは有用であることを期待して配布されていますが、商品性または特定目的への適合性の保証を含む、いかなる保証もありません。詳細についてはGNU一般公衆ライセンスを参照してください。
このプログラムとともにGNU一般公衆ライセンスのコピーを受け取っているはずです。受け取っていない場合は、http://www.gnu.org/licenses/ を参照してください。
