Agon Light およびその他の Agon プラットフォーム リビジョンは、Zilog eZ80 プロセッサに基づいています。 eZ80 は、オリジナルの Z80 の 64 キロバイトと比較して、16 メガバイトのメモリをサポートする 24 ビット アドレス空間を備えています。 eZ80 には 2 つの動作モードがあります。標準 Z80 モードには 16 ビット レジスタがあり、64k のメモリを簡単にアドレス指定できますが、64k を超えるメモリにアクセスするには「バンキング」の使用が必要です。 ADL (アドレス データ ロング) 動作モードでは、レジスタが 24 ビットに拡張され、アドレス空間全体に簡単にアクセスできるようになります。
高級プログラミング言語を考慮すると、Z80 で使用できる言語は多数ありますが、メモリが 64k に制限されているか、より多くのメモリにアクセスするためのバンク切り替え方法が厄介です。
C プログラミング言語を考慮すると、多数の Z80 C コンパイラが利用可能です。これまで、Agon コミュニティは次の 2 つに焦点を当ててきました。
eZ80 ADL コードを生成できるZilog ZDS II 開発環境。これは Agon の開発者が使用したオリジナルのツール セットですが、クローズド ソースであり、Windows 上でのみ実行され、データ C89 標準のみをサポートしています。
SDCC (スモール デバイス C コンパイラー) は、8 ビット コンピューターでよく使用される選択肢であり、これを Agon に適応させることは、Agon コンピューターの多くの人々の焦点となっています。これは Z80 に適したコンパイラですが、Z80 のみをサポートし、ADL モードはサポートしません。
代わりに、CEdev C/C++ ツールチェーンは、ADL コードを生成できるオープンソース コンパイラーです。これは TI-84 Plus CE 電卓 (eZ80 プロセッサをベース) を対象としており、適度な規模のコミュニティがあります。 CEdev は、LLVM コンパイラおよび fasmg アセンブラの eZ80 バージョンに基づいています。 24 ビット ポインター、24 ビット整数、32 ビット長、16 ビット短、および 32 ビット浮動小数点を含む ADL コードを生成します。 C および C++ プログラム用の非常に広範なライブラリもあります (ただし、まだ ISO に準拠していません)。
AgDev は、Agon プラットフォームの機能セットとハードウェア設計に合わせて CEdev を変更する取り組みの結果です。その結果、Agon の他のオプションと比較して、より強力で C++ 対応のツールチェーンが実現しました。
リリース ビルドをダウンロードするか、ソースから自分でビルドします。選択したディレクトリにビルドを配置します。
その後、 /bin
フォルダーがPATH
にあることを確認してください。 Windows を使用している場合は、このガイドに従うか、代わりに cedev.bat を実行してそこからコマンドを実行することもできます。 Linux では、ターミナル ウィンドウでexport PATH=/<insert path here>/bin:$PATH
実行します。
これは、元の CE ツールチェーンと同じアプローチに従います (CEdev 入門ページの下部を参照)。ビルド プロセスは、 .bin
ファイルの生成時に停止するように変更されていました。これは Agon Light 実行可能ファイルです。
以下を使用することをお勧めします。
きれいにする V=1にする
make clean
コマンドを使用すると、以前のコンパイルの結果を削除し、再コンパイルを強制できます。
ビルド プロセスは次の手順を実行します。
ez80-clang
を使用した .c ソース ファイルの LLVM ビットコード (.bc) へのコンパイル
ez80-link
を使用した LLVM ビットコードのリンク。これにはリンク時間の最適化が含まれます
ez80-clang
を使用したソースプログラム用のeZ80アセンブリコード(.src)の生成
fasmg
使用した、生成されたアセンブリ コード (ステップ 3 から) のライブラリおよびコンパイラ ランタイムとのアセンブルとリンク。これには、特定のメモリ位置を対象とした実行可能ファイルのビルドが含まれます。これは、調整が必要なビルド プロセスの主要な部分です。
Zilog アプリケーション ノート「asm.pdf からの C の呼び出し」を参照してください。
呼び出された関数によって保存される必要があるのは、IX レジスタとスタックだけです。
引数は、C プロトタイプに対応して最後から最初にプッシュされます。 eZ80 では、実際のサイズに関係なく、常に 3 バイトがスタックにプッシュされます。ただし、アセンブリ関数は、プッシュされた有効なバイトのみを使用するように注意する必要があります。たとえば、 short型が使用される場合、スタックにプッシュされる値の上位バイトには任意のデータが含まれます。この表には、呼び出された関数内のspに相対的な位置がリストされています。 sp + [0,2]
には戻りアドレスが含まれることに注意してください。
C/C++ タイプ | サイズ | スタックの場所 |
---|---|---|
チャー | 1バイト | sp+[3] |
短い | 2バイト | sp + [3,4] |
整数 | 3バイト | sp + [3,5] |
長さ | 4バイト | sp + [3,6] |
長い長い | 8バイト | sp + [3,10] |
フロート | 4バイト | sp + [3,6] |
ダブル | 4バイト | sp + [3,6] |
ポインタ | 3バイト | sp + [3,5] |
eZ80 はリトル エンディアンであることに注意してください。つまり、最下位バイトが最初に格納されます。
この表は、関数からの戻り値にどのレジスタが使用されるかを示しています。型の符号は使用されるレジスタには影響しませんが、返される値には影響する可能性があります。 LSB は式の右端のレジスタにあります。たとえば、 E:UHL
レジスタL
に LSB が格納されることを示します。
C/C++ タイプ | リターンレジスター |
---|---|
チャー | あ |
短い | HL |
整数 | UHL |
長さ | E:UHL |
長い長い | BC:UDE:UHL |
フロート | E:UHL |
ダブル | E:UHL |
ポインタ | UHL |
ISO に準拠していません。
以下のもので構成されます。
ファイルIO:
fopen()
、 freopen(),
fclose()
fputc()
、 fputs()
fgetc()
、 ungetc()
、 fgets()
feof()
、 ferror()
、 fflush()
fread()
、 fwrite()
fseek()
、 rewind()
、 ftell()
clearerr()
remove()
標準入力/標準出力 IO:
putchar()
、 puts()
getchar()
、 gets_s()
フォーマットされた出力
printf()
(およびvprintf()
)
sprintf()
(およびvsprintf()
)
snprintf()
(およびvsnprintf()
)
フォーマットされた入力
scanf()
sscanf()
ここには他にもstdint
などのものがいくつかありますが、通常の標準ライブラリの期待とほぼ一致するはずです。たいてい。
stdio
入出力リダイレクトstdout
またはstderr
でfreopen()
を使用して出力をリダイレクトできます。
putchar()
- 出力がリダイレクトされない限りoutchar()
に出力します。リダイレクトされた場合はfputc()
に出力します。
puts()
- putchar()
を呼び出します
printf()
(およびvprintf()
) - npf_putc_std()
を呼び出します。これはnanoprintf.c
のputchar()
を呼び出します。
fputc()
- outchar()
) を呼び出すときにstdout
で呼び出されない限り、 mos_fputc()
を呼び出します - 関数呼び出しループのリスクがないようにputchar()
呼び出しを回避します
stdin
でfreopen()
使用して入力をリダイレクトできます。
getchar()
- inchar()
を呼び出して文字を取得し、 outchar()
呼び出して文字をエコーします (出力がリダイレクトされた場合でも)。出力がリダイレクトされていない場合は、 fgetc()
が呼び出され、文字はエコーされません。
gets_s()
- 入力がリダイレクトされていない場合 (行が CR で終了している場合) getchar()
を呼び出します。入力のfgets()
呼び出しがリダイレクトされました (行は CR/LF ペアで終了します)。
scanf()
- uscan.c
のgetchar()
を呼び出します (更新する必要はありません)
fgetc()
- inchar()
を呼び出すときに標準入力で呼び出されない限りmos_fgetc()
呼び出し、 outchar()
でエコーします - getchar()
の呼び出しを回避するため、関数呼び出しループのリスクがありません
FILE *
が必要です。これは、 fopen
によって返され、アクションが実行されるファイルを示すためにファイル IO ルーチンに渡されるファイル ハンドルへのポインタです。
その他の関連ファイル:
stdio.h
- 通常のヘッダー ファイル。さまざまな関数とFILE
の typedef を定義します。
files.c
- stdout、stderr、stdin などのファイル ハンドルのストレージをインスタンス化します。
次の標準ファイル ハンドルが定義されています。
stdout
- デフォルトの出力
stderr
- エラーメッセージのデフォルト出力
stdin
- デフォルトの入力
MOS は入出力リダイレクトを実装していないため、デフォルトではこれらはすべてコンソールを使用します。
コマンドライン処理には 2 つのオプションが使用できます。
main 関数が次のように定義されている場合、これは自動的に組み込まれます。
int main( int argc, char* argv[] )
スペースを区切り文字として使用してコマンドラインを分割します。コマンド ライン オプションは、通常どおりargv[]
配列で使用できます。
アプリケーションのメイクファイルに以下が含まれる場合、これはオプションで含まれます。
LDHAS_ARG_PROCESSING = 1
これはサポートします
二重引用符で引用する
入出力リダイレクト
>out_file.txt
- stdout をout_file.txt
にリダイレクトし、新しいファイルを作成します
>>out_file.txt
- stdout をout_file.txt
にリダイレクトし、ファイルの末尾に追加します
<in_file.txt
- 標準入力をin_file.txt
からリダイレクトします
MOS コマンドに関する現在のドキュメントについては、Agon Console8 ドキュメントを参照してください。
MOS (マシン オペレーティング システム) は、Agon ファイル システムおよびマウスなどの一部のハードウェア周辺機器へのインターフェイスを提供します。システム変数に関する情報は、Z80 側からアクセスできる大きなSYSVAR
構造体に保持されます。通常、C コードは次のように初期化されたこの構造体へのポインターを宣言します。
静的揮発性 SYSVAR* sv; sv = vdp_vdu_init();
詳細については、 <mos_api.h>
を参照してください。
VDU コマンドに関する現在のドキュメントについては、Agon Console8 ドキュメントを参照してください。
VDP (ビデオ ディスプレイ プロセッサ) は、MOS からのテキスト ストリームを受け入れ、テキスト/グラフィックス端末のように動作します。テキスト ストリームには次のものを含めることができます。
通常のテキスト
エスケープ シーケンス / ディスプレイを制御し、グラフィックス/サウンド/その他のコマンドを送信するコマンド
コマンドの送信の結果として MOS によって結果が返される場合、これらはSYSVAR
に格納され、コマンドに直接応答して返されることはありません。応答は非同期です - 結果が返されたことを確認するには、次のようにします。
SYSVAR
のvdp_pflags
ゼロに設定します
VDUコマンドを発行します。
vdp_pflags
内の関連ビットが設定されるまで待ちます。ビット マスクについては、 <mos_api.h>
を参照してください。
コマンドは次の方法で送信できます。
putch()
- 単一文字 (これは C 標準ライブラリの一部ではありません)
mos_puts()
- 複数文字の文字列
これらは両方とも MOS/VDP に直接出力されます。これらは STDIO ライブラリの一部ではなく、CR/LF 変換やリダイレクトの対象ではないことに注意してください。
多くの VDU コマンド用の便利な関数が AgDev で提供されています。たとえば、画面 MODE を 3 に変更するには、C はvdp_mode(3);
22,3
単一バイトとして出力に送信します。これはputch(22); putch(3);
これらの関数のリストについては、 <vdp_vdu.h>
を参照してください。キーボード処理に関連する追加関数は、 <vdp_key.h>
にあります。