Agon Light 和其他 Agon 平台版本均基於 Zilog eZ80 處理器。 eZ80 具有 24 位元位址空間,支援 16 MB 內存,而原始 Z80 為 64 KB。 eZ80 有兩種操作模式:標準 Z80 模式,具有 16 位元暫存器,可以輕鬆定址 64k 內存,但需要使用「banking」來存取超過 64k 的記憶體; ADL(位址資料長)操作模式,將暫存器擴展到 24 位,使整個位址空間易於存取。
當我們考慮高級程式語言時,Z80 有多種可用的語言,但它們僅限於 64k 內存,或具有笨拙的存儲器切換方法來存取更大的內存。
考慮到 C 程式語言,有許多可用的 Z80 C 編譯器。迄今為止,Agon 社區主要關注兩個方面:
Zilog ZDS II開發環境,可以產生eZ80 ADL程式碼。這是 Agon 開發人員使用的原始工具集,但它是閉源的,僅在 Windows 上運行,並且僅支援資料 C89 標準
SDCC(小型裝置 C 編譯器)是 8 位元電腦的熱門選擇,並將其應用於 Agon 一直是 Agon 電腦中許多人關注的焦點。這是一個很好的 Z80 編譯器,但它只支援 Z80,不支援 ADL 模式。
作為替代方案,CEdev C/C++ 工具鍊是一個可以產生 ADL 程式碼的開源編譯器。它針對 TI-84 Plus CE 計算器(基於 eZ80 處理器),並擁有一個規模合理的社群。 CEdev 是基於 eZ80 版本的 LLVM 編譯器和 fasmg 彙編器。它產生具有 24 位元指標、24 位元整數、32 位元長整數、16 位元短整型和 32 位元浮點型的 ADL 程式碼。還有相當廣泛的 C 和 C++ 程式庫(儘管它還不符合 ISO 標準…)。
AgDev 是修改 CEdev 以適應 Agon 平台的功能集和硬體設計的努力的結果。與 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 個位元組壓入堆疊。但是,彙編函數必須小心,僅使用推送的有效位元組。例如,如果使用短類型,則壓入堆疊的值的高位元組將包含任意資料。此表列出了被呼叫函數內相對於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 |
整數 | 超HL |
長的 | E:UHL |
長長 | BC:UDE:UHL |
漂浮 | E:UHL |
雙倍的 | E:UHL |
指針 | 超HL |
不符合 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 mos_fputc()
時在stdout
上調用,否則調用 mos_fputc outchar()
- 避免調用putchar()
這樣就不會出現函數調用循環的風險
可以透過在stdin
上使用freopen()
來重定向輸入:
getchar()
- 呼叫inchar()
來取得字符,並呼叫outchar()
來回顯該字元(即使輸出已被重定向)。如果輸出尚未重定向,則呼叫fgetc()
且不回顯該字元。
gets_s()
- 如果輸入尚未重定向(行以 CR 終止),則呼叫getchar()
。輸入的呼叫fgets()
已被重定向(行以 CR/LF 對終止)。
scanf()
- 呼叫uscan.c
中的getchar()
(不需要更新)
fgetc()
- 除非在調用inchar()
時在 stdin 上調用,否則調用mos_fgetc()
並使用outchar()
進行回顯 - 避免調用getchar()
這樣就不會出現函數調用循環的風險
需要FILE *
,它是指向fopen
返回的檔案句柄的指針,並傳遞給檔案 IO 例程以指示要對其執行操作的檔案。
其他相關文件:
stdio.h
- 普通頭文件,定義各種函數和FILE
的 typedef
files.c
- 實例化檔案句柄的存儲,包括:stdout、stderr、stdin。
定義了以下標準檔案句柄:
stdout
- 預設輸出
stderr
- 錯誤訊息的預設輸出
stdin
- 預設輸入
MOS 沒有實現輸入/輸出重定向,所以預設情況下這些都使用控制台。
有兩個選項可用於命令列處理。
如果主函數定義為,則會自動包含此內容
int main( int argc, char* argv[] )
使用空格作為分隔符號來分割命令列。命令列選項照常在argv[]
陣列中可用。
如果應用程式 makefile 包含以下內容,則可以選擇包含此內容:
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 檔案系統和一些硬體週邊(如滑鼠)的介面。它將系統變數的資訊保存在一個大型SYSVAR
結構中,可以在 Z80 端存取。一般來說,你的 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 轉換或重定向的影響。
AgDev 中提供了許多 VDU 指令的便利功能。例如,要將螢幕模式變更為 3,C 呼叫vdp_mode(3);
將22,3
作為單一位元組傳送到輸出,相當於putch(22); putch(3);
有關這些函數的列表,請參閱<vdp_vdu.h>
。與鍵盤處理相關的其他函數可在<vdp_key.h>
中找到。