超級任天堂程式設計/超級FX教程
超級FX是一款為SNES設計的定製16位RISC處理器,具有特殊的點陣圖模擬功能。它旨在為SNES帶來基本的3D功能。它的程式設計是用特殊的超級FX組合語言完成的。每個超級FX遊戲都結合了標準的SNES彙編程式碼和專門編譯的超級FX彙編例程,這些例程以二進位制資料的形式編碼在遊戲卡中。它可以在某些條件下與SNES並行執行。每個超級FX遊戲卡都有板載RAM,超級FX晶片使用它作為幀緩衝區以及用於它可以與SNES共享的通用操作。
超級FX晶片被用於8款已釋出的SNES遊戲中,在《星際火狐2》(未釋出)以及多個技術演示中;其中有2款的二進位制檔案可供使用。
| 標題 | 超級FX版本 | ROM大小 | 遊戲卡RAM大小 | 存檔RAM大小 |
|---|---|---|---|---|
| 《星際火狐》(PAL: 《星際之翼》) | 馬里奧晶片 | 8 MBit | 256 KBit | 無 |
| 越野賽車 | GSU-1 | 4 MBit | 256 KBit | 無 |
| 塵土飛揚FX | GSU-1 | 4 MBit | 512 KBit | 無 |
| 《特技賽車FX》(JP: 《狂野賽道》) | GSU-1 | 8 MBit | 512 KBit | 64KBit |
| 星際火狐2 | GSU-1 | 8 MBit | 512 KBit | 64KBit |
| 漩渦 | GSU-1 | 4 MBit | 256 KBit | 無 |
| SNES體素景觀演示 | GSU-1 | 3 MBit | 512 KBit | 無 |
| 飄移(演示) | GSU-1 | 3 MBit | 512 KBit | 無 |
| DOOM | GSU-2 | 16 MBit | 512 KBit | 無 |
| 耀西島 | GSU-2-SP1 | 16 MBit | 256 KBit | 64KBit |
| 冬日黃金 | GSU-2 | 16 MBit | 512 KBit | 64KBit |

超級FX是SNES CPU的協處理器。超級FX的任務是執行比SNES快得多的複雜數學計算,併為超級FX遊戲的簡單3D渲染生成點陣圖。超級FX和SNES處理器共享對公共遊戲卡RAM和ROM匯流排的訪問。在任何時候,只有一個處理器,超級FX或SNES CPU,可以訪問遊戲卡RAM和/或ROM,由特殊暫存器控制。SNES和超級FX訪問資料匯流排的流程是最佳化程式效率的一門藝術。
遊戲卡RAM主要用於儲存計算結果、超級FX程式、批次資料或超級FX正在生成的PLOT影像。可以有256 Kib(32KiB)或512 Kib(64 KiB)的RAM。一些超級FX遊戲還使用此RAM來儲存存檔資料。
超級FX可以以3種方式處理指令:從遊戲卡RAM中讀取、從遊戲卡ROM中讀取(直接從ROM晶片讀取),或透過特殊的512位元組指令快取讀取。
當使用512位元組指令快取時,超級FX可以與SNES CPU並行執行。這涉及載入程式,然後設定超級FX以開始工作。與在遊戲卡RAM或ROM中執行程式相比,512位元組快取通常快3倍。超級FX可以在處理完成後中斷SNES CPU。
當使用超級FX的特殊點陣圖功能時,可以快速將點陣圖從遊戲卡RAM載入到SNES影片RAM並顯示在螢幕上。SNES預設是一個基於瓷磚和精靈的控制檯 - 3D渲染遊戲中使用的基於畫素的場景構建對於庫存的SNES硬體來說非常低效。在超級FX遊戲中,例如DOOM、星際火狐/星際之翼等,超級FX快速將基於畫素的場景點陣圖繪製到遊戲卡RAM上,然後將其扔到SNES VRAM中,以便每秒多次顯示圖形。
超級FX有3個不同的硬體版本。所有版本在指令集方面功能上都是相容的,但支援不同的ROM大小。
- MARIO晶片 - 代表“數學阿格諾特旋轉輸入輸出”。超級FX晶片的第一個版本,僅與星際火狐/星際之翼一起使用。晶片有兩個版本 - 一個是直接PCB裸片粘合/環氧樹脂設定,另一個是標準晶片載體封裝。
- GSU-1 - 用於大多數超級FX遊戲的版本,採用標準晶片載體封裝。在功能上與MARIO晶片相同。支援最大8兆位(1兆位元組)的ROM大小。
- GSU-2 - 用於最後3款超級FX遊戲,支援完整的16兆位(2兆位元組)ROM大小。
-
MARIO晶片(封裝)
-
MARIO晶片(環氧樹脂)
-
GSU-1
-
GSU-2
-
GSU-2 SP1
超級FX晶片有16個通用16位暫存器,標記為R0到R15,以及11個控制暫存器。此外,從$3100-$32FF的記憶體空間構成指令快取。
通用暫存器
| 暫存器 | 地址 | 描述 | 從SNES訪問 |
R0 |
$3000 |
預設源/目標暫存器 | R/W |
R1 |
$3002 |
畫素繪圖X位置暫存器 | R/W |
R2 |
$3004 |
畫素繪圖Y位置暫存器 | R/W |
R3 |
$3006 |
用於一般用途 | R/W |
R4 |
$3008 |
lmult 的低16位結果 | R/W |
R5 |
$300A |
用於一般用途 | R/W |
R6 |
$300C |
fmult 和 lmult 的乘數 | R/W |
R7 |
$300E |
用於合併的定點紋素X位置 | R/W |
R8 |
$3010 |
用於合併的定點紋素Y位置 | R/W |
R9 |
$3012 |
用於一般用途 | R/W |
R10 |
$3014 |
用於一般用途 | R/W |
R11 |
$3016 |
由 link 設定的返回地址 | R/W |
R12 |
$3018 |
迴圈計數器 | R/W |
R13 |
$301A |
迴圈點地址 | R/W |
R14 |
$301C |
用於GETB、GETBH、GETBL、GETBS的rom地址 |
R/W |
R15 |
$301E |
程式計數器 | R/W |
控制暫存器
| 名稱 | 地址 | 描述 | 大小 | 從SNES訪問 |
SFR |
$3030 |
狀態標誌暫存器 | 16位 | R/W |
$3032 |
未使用 | |||
BRAMR |
$3033 |
備份RAM暫存器 | 8位 | W |
PBR |
$3034 |
程式庫暫存器 | 8位 | R/W |
$3035 |
未使用 | |||
ROMBR |
$3036 |
rom庫暫存器 | 8位 | R |
CFGR |
$3037 |
控制標誌暫存器 | 8位 | W |
SCBR |
$3038 |
螢幕基址暫存器 | 8位 | W |
CLSR |
$3039 |
時鐘速度暫存器 | 8位 | W |
SCMR |
$303A |
螢幕模式暫存器 | 8位 | W |
VCR |
$303B |
版本程式碼暫存器(只讀) | 8位 | R |
RAMBR |
$303C |
RAM庫暫存器 | 8位 | R |
$303D |
未使用 | |||
CBR |
$303E |
快取基址暫存器 | 16位 | R |
指令快取
| 名稱 | 地址 | 描述 | 大小 | 從SNES訪問 |
1 |
$3100 |
指令快取的第一個位元組 | 8位 | R/W |
2 |
$3101 |
指令快取的第二個位元組 | 8位 | R/W |
| ... | ... | ... | 8位 | R/W |
| ... | ... | ... | 8位 | R/W |
512 |
$32FF |
指令快取的第512個位元組 | 8位 | R/W |
SFR 是一個非常重要的暫存器。它在評估計算後控制 Super FX 內部的分支,並且可以在從 SNES CPU 訪問時確定 Super FX 的狀態。
| 位 | 描述 |
|---|---|
| 0 | - |
| 1 | Z 零標誌 |
| 2 | CY 進位標誌 |
| 3 | S 符號標誌 |
| 4 | OV 溢位標誌 |
| 5 | G Go 標誌(當 GSU 執行時設定為 1) |
| 6 | R 使用 R14 地址讀取 ROM 時設定為 1 |
| 7 | - |
| 8 | ALT1 下一條指令的模式設定標誌 |
| 9 | ALT2 下一條指令的模式設定標誌 |
| 10 | IL 立即較低 8 位標誌 |
| 11 | IH 立即較高 8 位標誌 |
| 12 | B 當執行 WITH 指令時設定為 1 |
| 13 | - |
| 14 | - |
| 15 | IRQ 當 GSU 引起中斷時設定為 1。當被 658c16 讀取時設定為 0 |
用於允許保護遊戲卡內備份 RAM(不要與遊戲卡 RAM 混淆)。位 0 可以設定為 0 以停用寫入備份 RAM,設定為 1 以啟用寫入。
| 位 | 描述 |
|---|---|
| 0 | BRAM 標誌(0 = 寫入停用,1 = 寫入啟用) |
| 1 | 未使用 |
| 2 | 未使用 |
| 3 | 未使用 |
| 4 | 未使用 |
| 5 | 未使用 |
| 6 | 未使用 |
| 7 | 未使用 |
當 Super FX 載入程式碼時,它引用 PBR 暫存器來指定正在使用的庫。LJMP 指令是用於更改此暫存器的常用方法。
| 位 | 描述 |
|---|---|
| 0 | A16 地址選擇 |
| 1 | A17 地址選擇 |
| 2 | A18 地址選擇 |
| 3 | A19 地址選擇 |
| 4 | A20 地址選擇 |
| 5 | A21 地址選擇 |
| 6 | A22 地址選擇 |
| 7 | A23 地址選擇 |
當使用 ROM 緩衝系統時,此暫存器指定要複製到緩衝區的遊戲卡 ROM 的庫。ROMB 指令是用於更改此暫存器的常用方法。
| 位 | 描述 |
|---|---|
| 0 | A16 ROM 地址選擇 |
| 1 | A17 ROM 地址選擇 |
| 2 | A18 ROM 地址選擇 |
| 3 | A19 ROM 地址選擇 |
| 4 | A20 ROM 地址選擇 |
| 5 | A21 ROM 地址選擇 |
| 6 | A22 ROM 地址選擇 |
| 7 | A23 ROM 地址選擇 |
控制時鐘倍頻器和中斷遮蔽。
| 位 | 描述 |
|---|---|
| 0 | 未使用 |
| 1 | 未使用 |
| 2 | 未使用 |
| 3 | 未使用 |
| 4 | 未使用 |
| 5 | MS0(0 = 標準,1 = 高速) |
| 6 | 未使用 |
| 7 | IRQ(0 = 正常,1 = 遮蔽) |
注意:如果透過 CLSR 標誌(1)設定為以 21.477 MHz 執行,MS0 標誌應設定為 0。
此暫存器設定圖形儲存區域的起始地址。它直接寫入,而不是透過特定的指令。
| 位 | 描述 |
|---|---|
| 0 | A10 螢幕基址選擇 |
| 1 | A11 螢幕基址選擇 |
| 2 | A12 螢幕基址選擇 |
| 3 | A13 螢幕基址選擇 |
| 4 | A14 螢幕基址選擇 |
| 5 | A15 螢幕基址選擇 |
| 6 | A16 螢幕基址選擇 |
| 7 | A17 螢幕基址選擇 |
控制 Super FX 晶片的時鐘頻率。
| 位 | 描述 |
|---|---|
| 0 | CLSR,0 = 10.738 MHz,1 = 21.477 MHz |
| 1 | 未使用 |
| 2 | 未使用 |
| 3 | 未使用 |
| 4 | 未使用 |
| 5 | 未使用 |
| 6 | 未使用 |
| 7 | 未使用 |
此暫存器為 PLOT 圖形加速例程設定顏色數量和螢幕高度,並另外控制 Super FX 或 SNES 是否控制遊戲卡 RAM 和 ROM。
| 位 | 描述 |
|---|---|
| 0 | 顏色模式 MD0 |
| 1 | 顏色模式 MD1 |
| 2 | 螢幕高度 HT0 |
| 3 | 遊戲卡 RAM 訪問 - RAN(0 = SNES,1 = Super FX) |
| 4 | 遊戲卡 ROM 訪問 - RON(0 = SNES,1 = Super FX) |
| 5 | 螢幕高度 HT1 |
| 6 | 未使用 |
| 7 | 未使用 |
螢幕高度真值表
| HT1 | HT0 | 模式 |
|---|---|---|
| 0 | 0 | 128 畫素 |
| 0 | 1 | 160 畫素 |
| 1 | 0 | 192 畫素 |
| 1 | 1 | OBJ 模式 |
顏色模式真值表
| MD1 | MD0 | 模式 |
|---|---|---|
| 0 | 0 | 4 色 |
| 0 | 1 | 16 色 |
| 1 | 0 | 未使用 |
| 1 | 1 | 256 色 |
可以使用此暫存器讀取正在使用的 Super FX 晶片的版本。
| 位 | 描述 |
|---|---|
| 0 | VC0 |
| 1 | VC1 |
| 2 | VC2 |
| 3 | VC3 |
| 4 | VC4 |
| 5 | VC5 |
| 6 | VC6 |
| 7 | VC7 |
在遊戲卡 RAM 和 Super FX 暫存器之間寫入時,此暫存器指定正在使用的遊戲卡 RAM 的庫。RAMB 指令是用於更改此暫存器的常用方法。位 0 用於將 RAM 庫設定為 $70 或 $71
| 位 | 描述 |
|---|---|
| 0 | A16(當為 0 時為 $70,當為 1 時為 $71) |
| 1 | 未使用 |
| 2 | 未使用 |
| 3 | 未使用 |
| 4 | 未使用 |
| 5 | 未使用 |
| 6 | 未使用 |
| 7 | 未使用 |
此暫存器指定遊戲卡 RAM 或 ROM 的地址,資料將從該地址載入到快取中。LJMP 和 CACHE 指令都是更改此暫存器的可接受方法。
| 位 | 描述 |
|---|---|
| 0 | -(讀取時始終為 0) |
| 1 | -(讀取時始終為 0) |
| 2 | -(讀取時始終為 0) |
| 3 | -(讀取時始終為 0) |
| 4 | A4 |
| 5 | A5 |
| 6 | A6 |
| 7 | A7 |
| 8 | A8 |
| 9 | A9 |
| 10 | A10 |
| 11 | A11 |
| 12 | A12 |
| 13 | A13 |
| 14 | A14 |
| 15 | A15 |
Super FX 介面:對映到 $3000-$32FF,在庫 $00-$3F 和 $80-$BF 中
遊戲 ROM:對映到 2 MiB,在庫 $00-$3F 中從 $8000-$FFFF 開始。從庫 $40-$5F 開始的 2 MiB 映象對映。
遊戲卡 RAM:對映到 128 KiB,從庫 $70:$0000 開始。前 8 KiB 映象到庫 $00-$3F 和 $80-$BF 中的每個 $6000。
遊戲備份 RAM:對映到 128 KiB,從庫 $78:$0000 開始
SNES CPU ROM:可以使用一個額外的 6 MiB ROM,該 ROM 僅對 SNES CPU 可訪問,但沒有 Super FX 遊戲超過 2 MiB。額外的 ROM 將對映在庫 $80-$BF 中從 $8000-$FFFF 開始,以及在庫 $C0-$FF 中從 $0000-$FFFF 開始
遊戲 ROM:對映到 2 MiB,在庫 $00-$3F 中從 $8000-$FFFF 開始。從庫 $40-$5F 開始的 2 MiB 映象對映。
遊戲卡 RAM:對映到 128 KiB,從庫 $70:$0000 開始。不應訪問 SNES 可以看到的其他記憶體位置。
注意:Super FX 透過三個庫控制暫存器訪問記憶體:程式庫暫存器 (PBR)、ROM 庫暫存器 (ROMBR) 和 RAM 庫暫存器 (RAMBR)
Super FX 指令集不同於 Super Nintendo 的原生指令集。它允許更快的、更復雜的 16 位數學運算,幷包含一些特定的圖形操作功能。
一些指令可以組裝成單個位元組。這是指令(半位元組)和引數(半位元組)合併到同一個儲存位元組中的地方。這使得執行速度更快,指令密度也更高。這些是在設計協處理器時要考慮的重要目標。其中一個指令是 ADC,它以 $5 開頭,並接收 16 個通用 Super FX 暫存器之一($0-$F)的引數。
相當多的指令需要在執行操作碼之前執行 ALT 指令。這會修改相同操作碼的行為,使其執行略微不同的操作。有 3 種可能的 ALT 程式碼——ALT1($3D)、ALT2($3E)和 ALT1+ALT2($3F)。在下表中,每個指令都列出了具體的 ALT 程式碼。
大多數指令依賴於預定義的指標來定位計算變數。這些是 FROM、TO 和 WITH 指令。TO 和 FROM 命令分別指定作為變數的通用暫存器和計算結果。WITH 在同一個命令中定義了變數和結果。變數和結果分別被稱為源和目標暫存器。
| 指令 | 描述 | ALT(十六進位制) | CODE(十六進位制) | ARG | 長度(位元組) | 位元組 | ATL1 | ALT2 | O/V | S | CY | Z | ROM | RAM | 快取 | 分類 | 備註 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ADC |
帶進位的加法 | 3D | 0x5 | Rn | 2 | 0 | 0 | 0 | * | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
ADC |
帶進位的加法 | 3F | 0x5 | #n | 2 | 0 | 0 | 0 | * | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
ADD |
加法 | 無 | 0x5 | Rn | 1 | 0 | 0 | 0 | * | * | * | * | 3 | 3 | 1 | 算術運算指令 | |
ADD |
加法 | 3E | 0x5 | #n | 2 | 0 | 0 | 0 | * | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
ALT1 |
設定 ALT1 模式 | 無 | 0x3D | / | 1 | / | 1 | / | / | / | / | / | 3 | 3 | 1 | 字首標誌指令 | |
ALT2 |
設定 ALT2 模式 | 無 | 0x3E | / | 1 | / | / | 1 | / | / | / | / | 3 | 3 | 1 | 字首標誌指令 | |
ALT3 |
設定 ALT3 模式 | 無 | 0x3F | / | 1 | / | 1 | 1 | / | / | / | / | 3 | 3 | 1 | 字首標誌指令 | |
AND |
邏輯與 | 無 | 0x7 | Rn | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 邏輯運算指令 | |
AND |
邏輯與 | 3E | 0x7 | #n | 2 | 0 | 0 | 0 | / | * | / | * | 6 | 6 | 2 | 邏輯運算指令 | |
ASR |
算術右移 | 無 | 0x96 | / | 1 | 0 | 0 | 0 | / | * | * | * | 3 | 3 | 1 | 移位指令 | |
BCC |
進位清零時跳轉 | 無 | 0x0C | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BCS |
進位置位時跳轉 | 無 | 0x0D | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BEQ |
相等時跳轉 | 無 | 0x09 | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BGE |
大於等於零時跳轉 | 無 | 0x06 | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BIC |
位清零掩碼 | 3D | 0x7 | Rn | 2 | 0 | 0 | 0 | / | * | / | * | 6 | 6 | 2 | 邏輯運算指令 | |
BIC |
位清零掩碼 | 3F | 0x7 | #n | 2 | 0 | 0 | 0 | / | * | / | * | 6 | 6 | 2 | 邏輯運算指令 | |
BLT |
小於零時跳轉 | 無 | 0x07 | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BMI |
負數時跳轉 | 無 | 0x0B | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BNE |
不相等時跳轉 | 無 | 0x08 | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BPL |
正數時跳轉 | 無 | 0x0A | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BRA |
始終跳轉 | 無 | 0x05 | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BVC |
溢位清零時跳轉 | 無 | 0x0E | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
BVS |
溢位置位時跳轉 | 無 | 0x0F | e | 2 | / | / | / | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
CACHE |
設定快取基址暫存器 | 無 | 0x02 | / | 1 | 0 | 0 | 0 | / | / | / | / | 3-4 | 3-4 | 1 | GSU 控制指令 | |
CMODE |
設定繪圖模式 | 3D | 0x4E | / | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 繪圖/相關指令 | |
CMP |
比較 | 3F | 0x6 | Rn | 2 | 0 | 0 | 0 | * | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
COLOR |
設定繪圖顏色 | 無 | 0x4E | / | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | 繪圖/相關指令 | |
DEC |
遞減 | 無 | 0xE | Rn | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 算術運算指令 | |
DIV2 |
除以 2 | 3D | 0x96 | / | 2 | 0 | 0 | 0 | / | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
FMULT |
分數有符號乘法 | 無 | 0x9F | / | 1 | 0 | 0 | 0 | / | * | * | * | 11 或 7 | 11 或 7 | 8 或 4 | 算術運算指令 | 週期取決於 CFGR 暫存器 |
FROM |
設定 Sreg | 無 | 0xB | Rn | 1 | / | / | / | / | / | / | / | 3 | 3 | 1 | 字首暫存器指令 | |
GETB |
從 ROM 緩衝區獲取位元組 | 無 | 0xEF | / | 1 | 0 | 0 | 0 | / | / | / | / | 3-8 | 3-8 | 1-6 | 資料從遊戲卡 ROM 傳輸到暫存器 | 週期因 ROM 緩衝區而異 |
GETBH |
從 ROM 緩衝區獲取高位元組 | 3D | 0xEF | / | 2 | 0 | 0 | 0 | / | / | / | / | 6-10 | 6-9 | 2-6 | 資料從遊戲卡 ROM 傳輸到暫存器 | 週期因 ROM 緩衝區而異 |
GETBL |
從 ROM 緩衝區獲取低位元組 | 3E | 0xEF | / | 2 | 0 | 0 | 0 | / | / | / | / | 6-10 | 6-9 | 2-6 | 資料從遊戲卡 ROM 傳輸到暫存器 | 週期因 ROM 緩衝區而異 |
GETBS |
從 ROM 緩衝區獲取有符號位元組 | 3F | 0xEF | / | 2 | 0 | 0 | 0 | / | / | / | / | 6-10 | 6-9 | 2-6 | 資料從遊戲卡 ROM 傳輸到暫存器 | 週期因 ROM 緩衝區而異 |
GETC |
從 ROM 獲取位元組到顏色暫存器 | 無 | 0xDF | / | 1 | 0 | 0 | 0 | / | / | / | / | 3-10 | 3-9 | 1-6 | 資料從遊戲卡 ROM 傳輸到暫存器 | 週期因 ROM 緩衝區而異 |
HIB |
暫存器高位元組的值 | 無 | 0xC0 | / | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 位元組傳輸指令 | |
IBT |
載入立即位元組資料 | 無 | 0xA | "Rn, #pp" | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 資料傳輸/立即資料到暫存器 | |
INC |
遞增 | 無 | 0xD | Rn | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 算術運算指令 | |
IWT |
載入立即字資料 | 無 | 0xF | "Rn, #xx" | 3 | 0 | 0 | 0 | / | / | / | / | 9 | 9 | 3 | 資料傳輸/立即資料到暫存器 | |
JMP |
跳轉 | 無 | 0x9 | Rn | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | "跳轉、分支和迴圈指令" | |
LDB |
從 RAM 載入位元組資料 | 3D | 0x4 | Rm | 1 | 0 | 0 | 0 | / | / | / | / | 11 | 13 | 6 | 資料從遊戲卡 RAM 傳輸到暫存器 | |
LDW |
從 RAM 載入字資料 | 無 | 0x4 | Rm | 1 | 0 | 0 | 0 | / | / | / | / | 10 | 12 | 7 | 資料從遊戲卡 RAM 傳輸到暫存器 | |
LEA |
載入有效地址 | 無 | 0xF | "Rn, xx" | 3 | 0 | 0 | 0 | / | / | / | / | 9 | 9 | 3 | 宏指令 | |
LINK |
連結返回地址 | 無 | 0x9 | #n | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | "跳轉、分支和迴圈指令" | |
LJMP |
長跳轉 | 3D | 0x9 | Rn | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | "跳轉、分支和迴圈指令" | |
LM |
"從 RAM 載入字資料,使用 16 位" | 3D | 0xF | "Rn, (xx)" | 2 | 0 | 0 | 0 | / | / | / | / | 20 | 21 | 11 | 資料從遊戲卡 RAM 傳輸到暫存器 | |
LMS |
"從 RAM 載入字資料,短地址" | 3D | 0xA | "Rn, (yy)" | 2 | 0 | 0 | 0 | / | / | / | / | 17 | 17 | 10 | 資料從遊戲卡 RAM 傳輸到暫存器 | |
LMULT |
16x16 有符號乘法 | 3D | 0x9F | / | 2 | 0 | 0 | 0 | / | * | * | * | 10 或 14 | 10 或 14 | 5 或 9 | 算術運算指令 | 週期取決於 CFGR 暫存器 |
LOB |
暫存器低位元組的值 | 無 | 0x9E | / | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 位元組傳輸指令 | |
LOOP |
迴圈 | 無 | 0x3C | / | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | "跳轉、分支和迴圈指令" | |
LSR |
邏輯右移 | 無 | 0x03 | / | 1 | 0 | 0 | 0 | / | 0 | * | * | 3 | 3 | 1 | 移位指令 | |
MERGE |
合併 R8 和 R7 的高位元組 |
無 | 0x70 | / | 1 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 位元組傳輸指令 | |
MOVE |
將字資料從 Rn' 移動到 Rn |
無 | 0x2n1n' | "Rn, Rn'" | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 資料從暫存器到暫存器的傳輸 | |
MOVES |
將字資料從 Rn' 移動到 Rn 並設定標誌 |
無 | 0x2nBn' | "Rn, Rn'" | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 資料從暫存器到暫存器的傳輸 | |
MULT |
有符號乘法 | 無 | 0x8 | Rn | 1 | 0 | 0 | 0 | / | * | / | * | 3 或 5 | 3 或 5 | 1 或 2 | 算術運算指令 | 週期取決於 CFGR 暫存器 |
MULT |
有符號乘法 | 3E | 0x8 | #n | 2 | 0 | 0 | 0 | / | * | / | * | 6 或 8 | 6 或 8 | 2 或 3 | 算術運算指令 | 週期取決於 CFGR 暫存器 |
NOP |
無操作 | 無 | 0x01 | / | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | GSU 控制指令 | |
NOT |
反轉所有位 | 無 | 0x4F | / | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | 位操作指令 | |
OR |
位或 | 無 | 0xC | Rn | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | 位操作指令 | |
OR |
位或 | 3E | 0xC | #n | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 位操作指令 | |
PLOT |
繪製畫素 | 無 | 0x4C | / | 1 | 0 | 0 | 0 | / | / | / | / | 3-48 | 3-51 | 1-48 | 繪圖/相關指令 | 週期因 RAM 緩衝區和程式而異 |
RAMB |
設定 RAM 資料庫 | 3E | 0xDF | / | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 庫設定指令 | |
ROL |
帶進位的左旋 | 無 | 0x04 | / | 1 | 0 | 0 | 0 | / | * | * | * | 3 | 3 | 1 | 移位指令 | |
ROMB |
設定 ROM 資料庫 | 3F | 0xDF | / | 2 | 0 | 0 | 0 | / | / | / | / | 6 | 6 | 2 | 庫設定指令 | |
ROR |
帶進位的右旋 | 無 | 0x97 | / | 1 | 0 | 0 | 0 | / | * | * | * | 3 | 3 | 1 | 移位指令 | |
RPIX |
讀取畫素顏色 | 3D | 0x4C | / | 2 | 0 | 0 | 0 | / | * | / | * | 24-80 | 24-78 | 20-74 | 繪圖/相關指令 | |
SBC |
帶進位的減法 | 3D | 0x6 | Rn | 2 | 0 | 0 | 0 | * | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
SBK |
"儲存字資料,上次使用的 RAM 地址" | 無 | 0x9 | / | 1 | 0 | 0 | 0 | / | / | / | / | 3-8 | 7-11 | 1-6 | 資料從暫存器傳輸到遊戲卡 RAM | |
SEX |
符號擴充套件暫存器 | 無 | 0x95 | / | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 位元組傳輸指令 | |
SM |
使用 16 位將字資料儲存到 RAM | 3E | 0xF | "Rn, (xx)" | 3 | 0 | 0 | 0 | / | / | / | / | 12-17 | 16-20 | 4-9 | 資料從暫存器傳輸到遊戲卡 RAM | 週期因 RAM 緩衝區和程式而異 |
SMS |
"將字資料儲存到 RAM,短地址" | 3E | 0xA | "Rn, (yy)" | 3 | 0 | 0 | 0 | / | / | / | / | 9-14 | 13-17 | 3-8 | 資料從暫存器傳輸到遊戲卡 RAM | 週期因 RAM 緩衝區和程式而異 |
STB |
將位元組資料儲存到 RAM | 3D | 0x3 | Rm | 2 | 0 | 0 | 0 | / | / | / | / | 6-9 | 8-14 | 2-5 | 資料從暫存器傳輸到遊戲卡 RAM | 週期因 RAM 緩衝區和程式而異 |
STOP |
停止處理器 | 無 | 0x00 | / | 1 | 0 | 0 | 0 | / | / | / | / | 3 | 3 | 1 | GSU 控制指令 | |
STW |
將字資料儲存到 RAM | 無 | 0x3 | Rm | 1 | 0 | 0 | 0 | / | / | / | / | 3-8 | 7-11 | 1-6 | 資料從暫存器傳輸到遊戲卡 RAM | 週期因 RAM 緩衝區和程式而異 |
SUB |
減法 | 無 | 0x6 | Rn | 1 | 0 | 0 | 0 | * | * | * | * | 3 | 3 | 1 | 算術運算指令 | |
SUB |
減法 | 3E | 0x6 | #n | 2 | 0 | 0 | 0 | * | * | * | * | 6 | 6 | 2 | 算術運算指令 | |
SWAP |
交換低位元組和高位元組 | 無 | 0x4D | / | 1 | 0 | 0 | 0 | / | * | / | * | 3 | 3 | 1 | 位元組傳輸指令 | |
TO |
設定 Dreg | 無 | 0x1 | Rn | 1 | / | / | / | / | / | / | / | 3 | 3 | 1 | 字首暫存器指令 | |
UMULT |
無符號乘法 | 3D | 0x8 | Rn | 2 | 0 | 0 | 0 | / | * | / | * | 6 或 8 | 6 或 8 | 2 或 3 | 算術運算指令 | 週期數取決於 CONFIG 暫存器 |
UMULT |
無符號乘法 | 3F | 0x8 | #n | 2 | 0 | 0 | 0 | / | * | / | * | 6 或 8 | 6 或 8 | 2 或 3 | 算術運算指令 | ? |
WITH |
設定 Sreg 和 Dreg | 無 | 0x2 | "Rn, ?" | ? | 1 | ? | ? | ? | ? | ? | ? | ? | ? | ? | 字首暫存器指令 | ? |
XOR |
位異或 | 3D | 0xC | Rn | 2 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 位操作指令 | ? |
XOR |
位異或 | 3F | 0xC | #n | 2 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 位操作指令 | ? |
對於某些指令,必須在執行指令之前指定 Sreg 和 Dreg。Sreg 是“源暫存器”,Dreg 是“目標暫存器”,每個都指定為 16 個通用暫存器之一。使用 TO、FROM 和 WITH 指令指定 Sreg 和 Dreg。
點陣圖模擬功能是 Super FX 的主要加速功能之一。它允許在幀緩衝區中使用基於畫素的著色方法,而不是 SNES VRAM 中基於圖塊的方法。對於 3D 渲染操作,需要一個快速的逐畫素著色器。Super FX 提供了框架,可以快速將單個畫素繪製到幀緩衝區,然後將繪製的影像傳輸到 SNES VRAM。
Super FX 有 4 個乘法指令。
MULT- 有符號 8 位 x 有符號 8 位,結果為有符號 16 位,儲存在 Dreg 中。UMULT- 無符號 8 位 x 無符號 8 位,結果為無符號 16 位,儲存在 Dreg 中。LMULT- 有符號 16 位 x 有符號 16 位,結果為有符號 32 位,MSB 儲存在 Dreg 中,LSB 儲存在 R4 中FMULT- 有符號 16 位 x 有符號 16 位,結果為有符號 32 位。
MULT/UMULT 指令比 LMULT/FMULT 指令更快。
雖然 SNES 組合語言程式可以使用常規的 65c816 編譯器進行編譯,但 Super FX 組合語言需要自定義編譯器。現有的 Super FX 遊戲中使用的原始編譯器沒有在封閉的開發社群之外發布。
一個名為 sfxasm 的開源編譯器可用於編譯 Super FX 程式。
編譯後,Super FX 程式將作為二進位制庫包含在 SNES 組合語言程式中。然後,SNES 程式指示 Super FX 使用打包在 ROM 中的預編譯程式。
當 SNES 啟動帶有 Super FX 遊戲時,Super FX 晶片處於閒置狀態,您無需執行任何操作即可啟動正常的 SNES 載入 ROM 和執行程式碼的程式。當 SNES 啟動並執行了一些啟動例程,並且通常已準備好後,您可以在程式中啟用 Super FX。注意,為了使模擬器支援 Super FX 指令,標題中的 $FFD6 位元組必須為 $13、$14、$15 或 $1A。$FFD5 位元組應為 $20。
在執行程式碼之前應初始化 Super FX 晶片。這包括設定基本配置暫存器。
SCBRSCMRCFGRCLSR
如前所述,程式碼可以透過三種不同的方式載入到 Super FX 中 - 來自遊戲卡 ROM、RAM 和 512 位元組快取。根據您想要使用哪種方式,程式略有不同。
- ROM 模式的好處是簡單,但代價是 Super FX 處理時會停止 SNES CPU。
- RAM 模式的優勢是能夠在 SNES CPU 已經忙碌的情況下執行一個大型 Super FX 程式,但代價是必須在執行之前將程式寫入遊戲卡 RAM 中。
- 快取模式的優勢是在 SNES 同時忙於遊戲卡 ROM 和 RAM 的情況下,執行一個小程式的速度比 ROM 或 RAM 模式快三倍,但代價是必須在執行過程之前將程式載入到快取記憶體中。
1. 設定程式庫暫存器 (PBR) 用於 SFX 程式開始的位置。
2. 程式設計 Super FX 中的程式計數器 (R15)。
3. 透過在 SFR 暫存器中設定 RON 標誌,使 Super FX 獨佔訪問 ROM。
1. 使用複製例程將程式從 ROM 傳輸到遊戲卡 RAM 中。
2. 設定程式基址暫存器 (PBR) 用於 SFX 程式開始的位置。
3. 寫入 Super FX 程式計數器 (R15)。
1. 使用複製例程將程式從 ROM 傳輸到快取 RAM ($3100-$31FF) 及以後。程式需要以每 16 位元組為一個塊的方式排列,否則 Super FX 將不會執行超出 16 位元組段的指令。這對小於 16 位元組的小程式也適用 - 要解決這個問題,請在第 16 個位元組 ($310F) 中寫入一些內容。
2. 寫入 Super FX 程式計數器 (R15),這通常為 0。
3. Super FX 程式將獨立於 SNES 執行,直到它遇到 STOP 指令。當它完成時,根據 SFR 配置中斷是否設定,它將在 SNES 上生成一箇中斷 (RTI 指令)。如果中斷被遮蔽,則 Super FX 將進入空閒模式,並等待 SNES 的下一個命令開始執行。
當 Super FX 發現 SNES 已經寫入其程式計數器暫存器 (R15) 時,處理開始。
Super FX 可以透過兩種方式之一停止 - 透過在 Super FX 的程式中執行 STOP 指令,或者透過 SNES 將 "0" 寫入 Super FX 的 SFR 暫存器中的 GO 標誌。
當 Super FX 讀取 Super FX STOP 指令時,它會呼叫 RTI 指令。可以透過在 SFR 暫存器中設定 IRQ 位來遮蔽中斷。如果中斷沒有被遮蔽,要確定它是螢幕消隱中斷還是 Super FX,請檢查 SFR 暫存器中的 IRQ 標誌位。