跳轉到內容

超級任天堂程式設計/超級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協處理器。

超級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大小。

暫存器

[編輯 | 編輯原始碼]

超級FX晶片有16個通用16位暫存器,標記為R0R15,以及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 用於GETBGETBHGETBLGETBS的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 狀態標誌暫存器

[編輯 | 編輯原始碼]

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

BRAMBR 備份 RAM 暫存器

[編輯 | 編輯原始碼]

用於允許保護遊戲卡內備份 RAM(不要與遊戲卡 RAM 混淆)。位 0 可以設定為 0 以停用寫入備份 RAM,設定為 1 以啟用寫入。

描述
0 BRAM 標誌(0 = 寫入停用,1 = 寫入啟用)
1 未使用
2 未使用
3 未使用
4 未使用
5 未使用
6 未使用
7 未使用

PBR 程式庫暫存器

[編輯 | 編輯原始碼]

當 Super FX 載入程式碼時,它引用 PBR 暫存器來指定正在使用的庫。LJMP 指令是用於更改此暫存器的常用方法。

描述
0 A16 地址選擇
1 A17 地址選擇
2 A18 地址選擇
3 A19 地址選擇
4 A20 地址選擇
5 A21 地址選擇
6 A22 地址選擇
7 A23 地址選擇

ROMBR 遊戲卡 ROM 庫暫存器

[編輯 | 編輯原始碼]

當使用 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 地址選擇

CFGR 配置暫存器

[編輯 | 編輯原始碼]

控制時鐘倍頻器和中斷遮蔽。

描述
0 未使用
1 未使用
2 未使用
3 未使用
4 未使用
5 MS0(0 = 標準,1 = 高速)
6 未使用
7 IRQ(0 = 正常,1 = 遮蔽)

注意:如果透過 CLSR 標誌(1)設定為以 21.477 MHz 執行,MS0 標誌應設定為 0。

SCBR 螢幕基址暫存器

[編輯 | 編輯原始碼]

此暫存器設定圖形儲存區域的起始地址。它直接寫入,而不是透過特定的指令。

描述
0 A10 螢幕基址選擇
1 A11 螢幕基址選擇
2 A12 螢幕基址選擇
3 A13 螢幕基址選擇
4 A14 螢幕基址選擇
5 A15 螢幕基址選擇
6 A16 螢幕基址選擇
7 A17 螢幕基址選擇

CLSR 時鐘暫存器

[編輯 | 編輯原始碼]

控制 Super FX 晶片的時鐘頻率。

描述
0 CLSR,0 = 10.738 MHz,1 = 21.477 MHz
1 未使用
2 未使用
3 未使用
4 未使用
5 未使用
6 未使用
7 未使用

SCMR 螢幕模式暫存器

[編輯 | 編輯原始碼]

此暫存器為 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 色

VCR 版本暫存器

[編輯 | 編輯原始碼]

可以使用此暫存器讀取正在使用的 Super FX 晶片的版本。

描述
0 VC0
1 VC1
2 VC2
3 VC3
4 VC4
5 VC5
6 VC6
7 VC7

RAMBR 遊戲卡 RAM 庫暫存器

[編輯 | 編輯原始碼]

在遊戲卡 RAM 和 Super FX 暫存器之間寫入時,此暫存器指定正在使用的遊戲卡 RAM 的庫。RAMB 指令是用於更改此暫存器的常用方法。位 0 用於將 RAM 庫設定為 $70$71

描述
0 A16(當為 0 時為 $70,當為 1 時為 $71
1 未使用
2 未使用
3 未使用
4 未使用
5 未使用
6 未使用
7 未使用

CBR 快取基址暫存器

[編輯 | 編輯原始碼]

此暫存器指定遊戲卡 RAM 或 ROM 的地址,資料將從該地址載入到快取中。LJMPCACHE 指令都是更改此暫存器的可接受方法。

描述
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

記憶體對映

[編輯 | 編輯原始碼]

從 SNES CPU 的角度來看

[編輯 | 編輯原始碼]

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 開始

從 Super FX 的角度來看

[編輯 | 編輯原始碼]

遊戲 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 程式碼。

大多數指令依賴於預定義的指標來定位計算變數。這些是 FROMTOWITH 指令。TOFROM 命令分別指定作為變數的通用暫存器和計算結果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 合併 R8R7 的高位元組 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。Sreg 是“源暫存器”,Dreg 是“目標暫存器”,每個都指定為 16 個通用暫存器之一。使用 TOFROMWITH 指令指定 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 指令更快。

編譯 Super FX 例程

[編輯 | 編輯原始碼]

雖然 SNES 組合語言程式可以使用常規的 65c816 編譯器進行編譯,但 Super FX 組合語言需要自定義編譯器。現有的 Super FX 遊戲中使用的原始編譯器沒有在封閉的開發社群之外發布。

一個名為 sfxasm 的開源編譯器可用於編譯 Super FX 程式。

編譯後,Super FX 程式將作為二進位制庫包含在 SNES 組合語言程式中。然後,SNES 程式指示 Super FX 使用打包在 ROM 中的預編譯程式。

在 SNES 程式中使用 Super FX

[編輯 | 編輯原始碼]

當 SNES 啟動帶有 Super FX 遊戲時,Super FX 晶片處於閒置狀態,您無需執行任何操作即可啟動正常的 SNES 載入 ROM 和執行程式碼的程式。當 SNES 啟動並執行了一些啟動例程,並且通常已準備好後,您可以在程式中啟用 Super FX。注意,為了使模擬器支援 Super FX 指令,標題中的 $FFD6 位元組必須為 $13$14$15$1A$FFD5 位元組應為 $20

初始化

[編輯 | 編輯原始碼]

在執行程式碼之前應初始化 Super FX 晶片。這包括設定基本配置暫存器。

  • SCBR
  • SCMR
  • CFGR
  • CLSR

選擇執行模式

[編輯 | 編輯原始碼]

如前所述,程式碼可以透過三種不同的方式載入到 Super FX 中 - 來自遊戲卡 ROM、RAM 和 512 位元組快取。根據您想要使用哪種方式,程式略有不同。

  • ROM 模式的好處是簡單,但代價是 Super FX 處理時會停止 SNES CPU。
  • RAM 模式的優勢是能夠在 SNES CPU 已經忙碌的情況下執行一個大型 Super FX 程式,但代價是必須在執行之前將程式寫入遊戲卡 RAM 中。
  • 快取模式的優勢是在 SNES 同時忙於遊戲卡 ROM 和 RAM 的情況下,執行一個小程式的速度比 ROM 或 RAM 模式快三倍,但代價是必須在執行過程之前將程式載入到快取記憶體中。

設定 - ROM 模式

[編輯 | 編輯原始碼]

1. 設定程式庫暫存器 (PBR) 用於 SFX 程式開始的位置。
2. 程式設計 Super FX 中的程式計數器 (R15)。
3. 透過在 SFR 暫存器中設定 RON 標誌,使 Super FX 獨佔訪問 ROM。

設定 - RAM 模式

[編輯 | 編輯原始碼]

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 標誌位。

華夏公益教科書