[NES] Prince of Persiaのレベル゚ディタを䜜成しおいたす。 第1ç«  知人

第1ç«  、 第2ç«  、 第3 ç«  、 第4 ç«  、 第5ç«  、 ゚ピロヌグ



免責事項


子䟛の頃、80幎代に生たれた倚くの人々のように、私にはDendyプレフィックスがありたした。 良き䞭囜人によっお私たちに莈られ、悪名高いスティヌパヌによっお配垃された日本のファミコンのクロヌンは、80幎代の倚くの子䟛時代を明るい色で塗りたした。 䜕床も、私がこれたで広く愛しおいたゲヌムを調べお、考えられるすべおの秘密を芋぀けたしたそしお、しばしば「秘密ず100,500 + 1ゲヌムを枡す」ずいう粟神で有名なタむトルの本がなく、その䟡倀はれロでした、私はそれらをプレむしたかったですたすたす、しかし、新しいレベル、新しい秘密、新しい機䌚がありたす。



䞀郚のゲヌムには組み蟌みのレベル゚ディタヌたずえば、Battle City、Fire'n'Ice、別名Solomon's Key 2が甚意されおいたしたが、もちろんそれらのほずんどはそのような機䌚を提䟛しおいたせんでした。 私は圓然新しいスヌパヌマリオブラザヌズでプレむしたかったああ、どのように私は䞭囜人を愛し憎んでいたか、圌は99から9を1カヌトリッゞでリリヌスし、レベルA-1、B-1、... Z-1は䞍可胜でした合栌するか、元のレベルの耇補ですが、テクスチャが倉曎されたした、Duck Tales 1、2、および他の倚くのもの。



コンピュヌタヌの出珟ずゲヌムの゚ミュレヌトの可胜性により、私の倢のトンネルの終わりに光が明かり、垌望が私の䞭に忍び蟌み始めたした。 さたざたなゲヌム゚ディタヌが登堎し始めたした。ROMファむルを瀺すだけで十分で、ゲヌムの秘密ず萜ずし穎をすべお芋るこずができるだけでなく、独自のものを远加するこずもできたす。



䞀方、䞀郚のゲヌムの線集者はGoogleの最初のリンクにほずんどありたしたが、他の線集者はどこか遠くに隠れおいたしたしかし、ただそこにいたした、たたはたったくありたせんでした。 お気に入りのゲヌムのほずんどの゚ディタヌを芋぀けたので、ペルシャ王子の゚ディタヌを芋぀けるこずができたせんでした。 はい、DOSバヌゞョン甚の゚ディタヌ、SNES甚の゚ディタヌがありたすが、私自身のNESバヌゞョンにはそのような宝物がありたせんでした。



NESずその゚ミュレヌションに関するさたざたな皮類のリ゜ヌスは、私の理解に屈するこずをあたり望んでおらず、noobレベルのどこかに留たりたした。



そしお、か぀お、か぀おないほど暑い日没の1時間で、モスクワでベルトを匕っ匵り、HEX゚ディタヌずデバッガヌで゚ミュレヌタヌを開き、ROMに含たれおいる神秘的なバむトセットを調べ始めたした。



私は始めたした...しかし、私がさらに話を始める前に、私は泚意したす

専門家のためにカットの䞋に行くこずは掚奚されたせん。 初心者の「フラッシュ」方法が考慮されおいたす あなたの神経系は䞍可逆的に損傷を受ける可胜性がありたす 譊告した。





本質を掘り䞋げる


HEX゚ディタヌで蚭定されたバむトず、圓時䞍明だった6502プロセッサヌ呜什のセットを芋るず、悲しかったです。 この党䜓像は䜕も明確にしたせんでした。 しかし、目は恐れおおり、手はしおいる。 䜕であるかを研究し始めたす。



NESヘッダヌ


これが衚面にある最初のものです。 圌から始めたしょう。

ヘッダヌのサむズは16バむトで、眲名に加えお、ROMファむルに関する技術情報がありたす。 ROMファむル自䜓は、1぀のファむル内のデヌタず技術情報の組み合わせです。 ヘッダヌの内郚を芋おください。

4E 45 53 1A 08 00 21 00 00 00 00 00 00 00 00 00





4バむト眲名NES->;

1バむト16 KB PRG-ROMバンクの数。

1バむト8 KB CHR-ROMバンクの数。

2バむトフラグ。

1バむト8 kB PRG-R A Mバンクの数。

2バむトフラグ。

残りのテヌルはれロです。



フラグには、ビデオメモリの操䜜に関する特定の情報、元のハヌドりェアの「バッテリヌ」の存圚、マッパヌ、およびその他の関心のない技術情報が栌玍されたすこの特定のケヌスでは必芁ないため、説明したせん。



ヘッダヌから、マッパヌ2マッパヌ番号を持぀バむトは6分の5バむトず7バむトで構成されおいたすず8 16 kB PRG-ROMバンクがあるこずがわかりたす。 他のすべおが欠萜しおいたす。



ドキュメンテヌションから、PRG-ROMバンクは実際にはコヌド+ CPUによっお盎接䜿甚される任意のデヌタであるこずがわかりたす。 CHR-ROMバンクは、ビデオサブシステムPPUのデヌタです。 CPUはそれらに盎接接続できたせん。

単䞀のCHR-ROMがない堎合、どのようにしお画像を取埗したすか 非垞に簡単PRGでは、PPUメモリに垞にコピヌされるデヌタを保存したす。 䞍䟿ですか はい しかし、このデヌタに関しおは、ある意味では、より匷力です。



さらに、Mapper2は実際には、機胜は同じであるが構造が異なる耇数の異なるマッパヌを意味するこずがわかりたす。UNROMずUOROM、UxROMの名前で結合されおいたす。 違いはPRG-ROMバンクの数のみです。最初は8バンク、2番目は-16です。いずれの堎合も、最埌のバンクはRAMの最埌に固定され$ C000- $ FFFF、残りの7たたは2番目の堎合は15を切り替えるこずができたす$ 8000- $ BFFFのメモリ領域に。

これはすべお、珟時点では賢明なこずを䜕も䌝えおいない技術情報です。



猶詰を買いだめ


したがっお、ROMファむルを9぀のコンポヌネントヘッダヌず8぀のバンクに分割できたす。 芋出しを線集しおも意味がありたせん。 ゚ミュレヌタプログラムの情報はそこに保存されおいたすが、銀行の線集方法はわかりたせん。 第䞀に、銀行には厳密な構造がなくたずえば、コヌドずリ゜ヌスがセクションにあるPE圢匏のように、デヌタをコヌドずランダムに混圚させるこずができたす。 たぶん、私たちはたったく幞運ではなかったかもしれず、レベルを構築するためのデヌタは実行可胜なコヌドによっお圢成されたす。



しかし、私たちはオプションを理解したすが、バむナリポリッゞ党䜓から必芁なものをどのように取埗したすか

  1. 最も耇雑であるが、最も普遍的なものであるシヌケンシャルリバヌスコヌドデバッガヌ。 この方法を䜿甚するず、必芁なものに確実に到達し、コヌドの䜜成方法に関する远加情報の圢でボヌナスが埗られたす。 マむナス面は明らかです。逆に倚くの時間を費やしたすが、これはそれほど悪いこずではありたせん。ただ䜕も知らないため、アセンブラヌずさたざたなプログラミング「トリック」の研究に90の時間を費やすこずになりたす。 ぀たり 効率は玄10です。 十分ではありたせん。
  2. RAMを調べ、メモリにアクセスするためのブレヌクポむントをデバッグしたす以䞋を参照。 この方法はすでに優れおいたす。 調査するメモリは比范的少なく、64 KBの䜿甚可胜なメモリのうち、半分はROMファむルからバンクに移動し、この半分はIOポヌトによっお予玄たたは䜿甚されおいたす。 そしお最埌に、残りの半分はただ半分に勝っおいたす。 半分はPPUのIOポヌトであり倚くはありたせんが、半分はミラヌリングされおいたす、もう1぀は2 kBの4぀の郚分に分割されたす。 最初の郚分はコヌドで䜿甚される実際のRAMで、残りの3぀は最初の郚分のミラヌです。 したがっお、孊習甚に2 kBのメモリが残っおおり、これは私の目で盎接孊習できたす。 メ゜ッドの効率はより高いです、なぜなら 目の前にラむブデヌタがあり、実行時に倉曎しお結果を確認できたす。
  3. 読み取りデヌタの調査。 別のレベルに移動するずき、たたは別の郚屋に移動するずきに、ROMファむルから読み取られたデヌタを調べたす。 思い出すように、プリンスオブペルシャでは、各レベルは郚屋に分割され、その間で実行されたす。
  4. 「Flayer」メ゜ッドは「Bruteforce」です。1バむトを連続的に倉曎し、結果のスクリヌンショットを撮り、なぜスクリヌンショットを調査するのかを説明したす。




必芁な量の材料を準備し、調査に進みたす。 私たちは逆の順序で孊習したす。単玔なものから孊習するものスクリヌンショットを芋るだけから耇雑なものデバッガヌのリストを調べるたでです。



ツヌルで歊装



始める前に、UxROMずは䜕かを芋おみたしょう。

䞀般的に蚀えば、マッパヌぱミュレヌタヌの芳点からはアルゎリズムであり、鉄の芳点からはメモリヌ内のバンクの切り替えを凊理する䞀皮のコントロヌラヌです。

最初なぜ圌はこれをしおいるのですか

第二に圌はどうやっおそれをするのですか



最初の質問ぞの答えは簡単ですプロセッサがアドレスできるRAMは倚くなく、64 kBだけで、コヌドずデヌタだけでなく、入力/出力ポヌトだけでなく、他のものそれが栌玍されおいる䞍揮発性メモリなどもプッシュする必芁がありたす䞀郚のゲヌムの䞭間結果。 コヌドを実行するず、メモリ内のすべおのデヌタが䜜業に必芁ずなるわけではないため、単玔にそれを陀倖しお、特定の時点でより重芁な堎所に配眮するこずができたす。 ROMメモリの隣に、コントロヌラがカヌトリッゞにむンストヌルされおおり、コマンドで、アドレスメモリ内の目的のピヌスを衚瀺したす。 ゲヌムの耇雑さに応じお、これらのコントロヌラヌは充填量が異なりたした。 䞀方、䞭囜人はこのビゞネスを時間通りに匕き受け、倚くの異なる適切な、そうでないマッパヌを思い付きたした。 これにより、倚数のマルチゲヌムがありたす。



2番目の質問では、UxROMマッパヌの操䜜のみを考慮したす。残りは今は興味を匕くものではないからです。 マッパヌは最埌のバンク07たたは0Fを取埗し、アドレス$ C000- $ FFFFに配眮しお、それ以䞊觊れたせん。 他のすべおのバンクは、バンク番号のスペヌス$ C000- $ FFFF00-06たたは00-0Eの任意のアドレスに蚘録した埌䞀般的な堎合、必芁に応じお含たれたす。 ただし、これは次のように正しく行われたす。アドレス$ FFF0 + Nに、Nが曞き蟌たれたすNはバンク番号。その結果、アドレス$ 8000- $ BFFFに、目的のバンクの内容が衚瀺されたす。



瓶をwithで切り刻みたす。 メ゜ッド番号4。


これを行うために、1バむト単玔な増分バむト++を倉曎し、別のファむルに保存し、゚ミュレヌタヌで受信したROMを起動し、スクリヌンショットを撮っお゚ミュレヌタヌを閉じる小さなナヌティリティを䜜成したした。

スクリヌンショットの数を枛らすのが賢明です。なぜなら、 130,000を超えるスクリヌンショットを孊習するには、倧雑把なスクリヌンショットでさえ困難です。



PRG-ROMバンクしか持っおいないので、それらのいく぀かはおそらく私たちにずっお興味のないタむルも保存しおいたす。 それらを陀倖しようずしたす。

任意のタむル゚ディタヌを䜿甚しお、その䞭のROMファむルを開きたす。 私はTile Layer Proを䜿甚したした。これは非垞に叀いプログラムですが、そのビゞネスを知っおいたす。 これは次のようなものです ゲヌムのファむナルファンタゞヌのスクリヌンショットタむル。 プログラムりィンドりのステヌタス行は、各タむルのオフセットを瀺したす。 デヌタりィンドりをスクロヌルしお、タむルが明らかに終了し、グラフィックスの芳点からの「ガベヌゞ」デヌタが始たるポむントたでスクロヌルできたす。 スクロヌルするず、最初の2぀のバンクがグラフィックであるこずがわかりたす。 それらをスキップし、6぀の銀行が残りたす。 すでに「唯䞀」96 kB。 難しいですが、それでも簡単です。



じゃあ この方法で必芁なデヌタをどのように芋぀けるこずができたすか 非垞に簡単です。スクリヌンショットを䞀目芋ただけで、䞀郚のスクリヌンショットでは、郚屋のブロックが埐々に倉曎されたす。 郚屋はそれぞれ10x3ブロックで構成され、30個のスクリヌンショットが連続しおいたす。隣接ブロックを他のブロックに倉曎する必芁がありたす。たずえば、「コンクリヌト」ブロックを列などに亀換できたす。



䞊べ替えナヌティリティを傍芳者のどこかで開始し、ROMから読み取ったデヌタの調査に進みたす。



猶の蓋を包䞁で切りたす。 メ゜ッド番号3。


この方法は前の方法ず䌌おいたすが、調査するデヌタの量を倧幅に削枛したす。 どうやっお

FCEUXDSPには、読み取ったデヌタを隣接するファむルに保存するツヌルがありたす。 [開始]ボタンず[䞀時停止]ボタンを抌す間、読み取られたデヌタは、元のファむルに保存されおいる堎所のファむルに正確に配眮されたす。 したがっお、デヌタ固定ダむアログを開き、[開始]をクリックしお、ある郚屋から別の郚屋にゲヌムを実行し、[䞀時停止]を抌しお、前の段萜ず同様に、蚘録されたデヌタを調べたす。 このデヌタは倧幅に少なくなりたす。 実際、コヌド自䜓は、泚意すべき点を瀺しおくれたす。 そしお、100バむトたたは2バむトの䜜業を敎理するのは手䜜業でさえありたせん。



これに぀いおは、䞀時停止し、キッチンに行き、コヌヒヌを入れお、6502プロセッサの指瀺に関するドキュメントを開くこずを提案したす。

方法番号2を䜿甚する前に、敵ず知り合うこずは害になりたせん。



内容物を調べるために顕埮鏡を眮きたす。 悪魔は描かれおいるほどひどいものではありたせん。


6502プロセッサには、 文曞化された呜什が56しかありたせんので、少なくずも1杯のコヌヒヌで十分に説明できたす。

コヌドをすぐに理解するのは難しいので、孊習甚の簡単なCラむクな蚀語を思い぀いたので、そこにアセンブリシヌトを簡単に翻蚳できたす。



たず、ドキュメントからいく぀かのポむントを匷調したす。

  1. アドレス指定には、盎接レゞスタ<->メモリIMMを䜿甚できたすLDA $ 00; STA $ 00;
  2. むンデックスレゞスタを盎接含むレゞスタ<->メモリ+むンデックスLDA $ 0000、X; STA $ 0000、Y;
  3. むンデックスレゞスタを含む間接レゞスタ<->ポむンタ+むンデックスLDA$ 00、X; STA$ 00、Y;


間接アドレス指定では、プロセッサは2぀のセル最初のメモリペヌゞ$ 00- $ FF内から16ビットポむンタヌを抜出し、むンデックスレゞスタの倀をそれに远加し、取埗したアドレスのセルを操䜜したす。



ここから、次の擬䌌コヌド芏則を䜜成したす。



簡単な銀行切り替えコヌドを取埗したす。

 $F2D3:84 41 STY $0041 = #$00 $F2D5:A8 TAY $F2D6:8D D1 06 STA $06D1 = #$06 $F2D9:99 F0 FF STA $FFF0,Y @ $FFF0 = #$00 $F2DC:A4 41 LDY $0041 = #$00 $F2DE:60 RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      
      





行ごずに翻蚳しおみたしょう

 char switch_bank() //       A { $0041 = Y; //  Y Y = A; $06D1 = A; //     #FFF0[Y] = A; //       $FFF0+N  N ( N -   ) Y = $0041; //   Y return A; }
      
      







それでは、もっず耇雑なコヌドを芋おみたしょう。



 ;;         PPU $F302:20 D3 F2 JSR $F2D3 $F305:8E 06 20 STX $2006 = #$41 $F308:A9 00 LDA #$00 $F30A:8D 06 20 STA $2006 = #$41 $F30D:A2 10 LDX #$10 $F30F:A0 00 LDY #$00 $F311:B1 17 LDA ($17),Y @ $020E = #$03 $F313:8D 07 20 STA $2007 = #$00 $F316:C8 INY $F317:D0 F8 BNE $F311 $F319:E6 18 INC $0018 = #$02 $F31B:CA DEX $F31C:D0 F1 BNE $F30F $F31E:4C 10 D0 JMP $D010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      
      







翻蚳の最初の段階

 char sub_F302() { sub_F2D3(); // switch bank. Bank counter in A register // $2006 – PPU Address register // $2007 – PPU data write //  $2006     // ( ,  ) // 2007       //  PPU.     PPU //    1. $2006 = X; //    $2006 = #00 //    X = #10; label_F30F: Y = #00; label_F311: //   $0017:$0018   // ,  ,     PPU $2007 = $0017[Y]; Y++; if ( Y != #00 ) goto label_F311; $0018++; X--; if ( X != #00 ) goto label_F30F; return sub_F2D3(#05); //  5-  }
      
      







そしお、翻蚳の最終段階

 void WriteDataIntoPPU(char Bank, char PPULine) { switch_bank(Bank); // switch bank. PPUADDRESS = PPULine; //    PPUADDRESS = #00; //    for(X = #10; X > 0; X--) { for(Y = #00; Y <= #FF; Y++) { PPUDATA = $Tiles[Y]; } $Tiles += #100; //     } return switch_bank5(); }
      
      





2぀の簡単な手順で、読みにくい初心者向けアセンブラヌリストをわかりやすいコヌドに曞き盎したした。 switch_bank5プロシヌゞャは考慮したせんでした。レゞスタAに番号05を割り圓おるための䞀般的なコヌドがあり、sub_F2D3バンクスむッチングプロシヌゞャが呌び出されたす。 コヌドを読み取り可胜なコヌドに倉換するずきに自動化を開発するには、3぀の手順をいく぀か行うだけで十分でした。 箄10〜5〜7 KBのテキストファむルを蓄積した埌、コヌドを翻蚳する必芁がなくなりたした。すべおが頭の䞭で自然に起こり始めたした。



私たちは花束ずキャンディヌ期間に枡したす


第2章では、最埌の2぀の方法に粟通し、NESの神秘的な䞖界に深く入り蟌みたす。 最埌に、最初の3぀の方法を組み合わせるこずで、必芁なデヌタを芋぀けるこずができたす。 4番目は明らかな欠点のために砎棄されたす。



「なぜあなたはそれを説明したしたか」ずいう質問の出珟を想定しお、私はすぐに答えたす䞻題を調べるずき、結果を䞎えるこずができるすべおの方法は良いです。 私たちの堎合、この方法は、コヌドの荒野に入らずに針を突き刺しおブラックボックスを調べる堎合に圹立ちたす。ある点に結果を䞎えおください。 この方法には、ブルヌトフォヌスの明らかな利点がありたす。 䜕らかの方法で、私たちは䜕かに぀たずきたす。



All Articles