SNES がオペコードとアドレス/パラメータをどのように理解するか理解に苦慮しています。各オペコードが一意の 16 進バイトでエンコードされていることはわかっています。それらは直後のバイトをパラメータ化していますか? その場合、1 バイトまたは 2 バイト (絶対アドレスまたは直接アドレスの場合) をどのように認識するのでしょうか。
この場合、ファイルの最初のバイト (ヘッダーの後の) がオペコードであることを意味しますか?
プロセッサには、次に実行する命令のアドレスを含む PC (プログラム カウンタ) レジスタがあります。リセット時に、PC は実行が開始される固定値に設定されます。
すべての命令の最初のバイトはオペコード バイトです。そのコーディングによって、命令が何を行うか、および必要なオペランドのバイト数が決まります。プロセッサは、PC のアドレスからオペコード バイトをフェッチし、PC をインクリメントします。オペコードが検査され、必要なオペランド バイトがあれば、常に PC が指すメモリからフェッチされます。PC は、1 バイトごとにインクリメントされます。完全な命令がフェッチされると、PC は次の命令のオペコードを指します。
次に、CPU はオペコード バイトとそのオペランドによって決定される操作を実行します。これは命令実行と呼ばれます。たとえば、ジャンプの場合、実行によって PC が変更される可能性がありますが、実行の最後に、PC は次に実行する命令のオペコード バイトを指し、フェッチ実行サイクルと呼ばれるサイクルが続行されます。
プログラムのバグは、プログラマー/コンパイラーによって書かれた命令の開始ではない値に PC が変更されるという事実が原因であることがよくあります。CPUはそれを知る方法がなく、実行することを意図していなかったメモリコンテンツを実行し、本質的にランダムな操作を実行します.
これがどのようにまとめられているかを理解するための優れたリソースはThe Elements of Computing Systemsです。これは書籍ですが、ほとんどのコンテンツはその Web サイトから入手できます。
それが役立つことを願っています。
この場合、ファイルの最初のバイト (ヘッダーの後の) がオペコードであることを意味しますか?
SNES の CPU は、6502 の一種の進化形である65C816に基づいています。下位互換性のために、65C816 には6502 (実際には 65C02) とバイナリ互換のエミュレーション モードが含まれています。また、16 ビット レジスタとすべてのジャズを備えたネイティブ モードもあります。
各モードには独自のベクトル テーブルがあります。
ネイティブ モード:
$FFE4: COP (co-processor interrupt)
$FFE6: BRK
$FFE8: ABORT
$FFEA: NMI (vertical blank)
$FFEC: - (no RESET in native mode)
$FFEE: IRQ
エミュレーション モード:
$FFF4: COP
$FFF6: -
$FFF8: ABORT
$FFFA: NMI (vertical blank)
$FFFC: RESET
$FFFE: IRQ or BRK
CPU がリセットされると、エミュレーション モードで起動し、論理アドレス$FFFC (対応する ROM 内の物理オフセットはメモリ マッピング モードによって異なります) で RESET ベクトルを見つけることを期待します。
RESET ベクターに格納されたアドレスは、リセット/電源サイクル後に実行する最初のコードを指している必要があります。通常、割り込みを無効にし、CPU をネイティブ モードに切り替え、システムの残りの部分 (グラフィック プロセッサ、サウンド プロセッサなど) を初期化することから始めます。
sei ; Disable interrupts
clc ; Clear the carry flag
xce ; Swap the carry and emulation flag (i.e. clear the emulation flag)
... ; Awesomeness follows..