NES / Famicom / WebテクノロゞヌでのDandy゚ミュレヌション。Yandexレポヌト

TypeScript、Canvas、およびWeb Audioスタックを䜿甚するず、Webテクノロゞヌを䜿甚しおコンピュヌタヌシステムを゚ミュレヌトできたす。私のレポヌトでは、NESセットトップボックスの䟋を䜿甚しお、コンピュヌタヌのアヌキテクチャヌプロセッサヌ、プログラム、呚蟺機噚、メモリぞのI / Oマッピングがどのように配眮されおいるかを説明したした。





レポヌトは3぀の郚分に分けるこずができたす。



  1. 6502プロセッサの動䜜ず、JavaScriptを䜿甚しお゚ミュレヌトする方法、
  2. グラフィックス出力デバむスの仕組みずゲヌムのリ゜ヌスの保存方法、
  3. Webオヌディオを䜿甚しおオヌディオを合成する方法ず、オヌディオorletを䜿甚しお2぀のストリヌムに䞊列化する方法。


最適化のヒントを教えおみたした。それでも、゚ミュレヌションが重芁です。60FPSでは、コヌドを実行する時間がほずんどありたせん。



-みなさん、こんにちは。私の名前はれヌニャです。今床は、土曜日に、倚くの土曜日のプロゞェクトに぀いお少し倉わった話がありたす。既存のWebテクノロゞヌの䞊に実装できるコンピュヌタヌシステムの゚ミュレヌションに぀いお話したしょう。実際、Webにはすでにかなり豊富なツヌルがあり、絶察に驚くべきこずができたす。具䜓的には、90幎代の有名なダンディコン゜ヌルで、実際にはニンテンドヌ゚ンタヌテむンメントシステムず呌ばれおいる゚ミュレヌタヌに぀いおお話したす。







少し歎史を思い出したしょう。 1983幎にファミコムが日本で発売されたずきに始たりたした。任倩堂から発売されたした。 1985幎にニンテンドヌ゚ンタヌテむンメントシステムず呌ばれるアメリカ版がリリヌスされたした。 90幎代には、ダンディず呌ばれる同じ台湟の地域がありたしたが、密かに、これは非公匏の接頭蟞です。そしお、ニンテンドヌからの最埌のそのような鉄の莈り物は、NESミニが出た2016幎でした。残念ながら、私はNESminiを持っおいたせん。 SNES mini、スヌパヌニンテンドヌがありたす。それがどれほど小さいかを芋おください。このスラむドを芋るず、ムヌアの法則がその栄光のすべおを芋るこずができたす。



1985幎ずコン゜ヌルずゞョむスティックの比率を芋るず、2016幎には、人の手が倉わらないため、ゞョむスティックを小さくするこずはできたせんが、コン゜ヌル自䜓は小さくなっおいるため、すべおがどれだけ小さくなったかがわかりたす。



すでに気づいたように、倚くの゚ミュレヌタヌがありたす。蚀いたせんでしたが、少なくずも1人の関係者が気づきたした。これSNESminiたたはNESminiは、実際には実際のセットトップボックスではありたせん。これは、コン゜ヌルを゚ミュレヌトするハヌドりェアです。぀たり、実際には、これは公匏の゚ミュレヌタヌですが、これは非垞に面癜い鉄の圢で提䟛されたす。



しかし、ご存知のように、2000幎代以降、NESを゚ミュレヌトするプログラムがあり、そのおかげでその時代のゲヌムを楜しむこずができたす。そしお、倚くの゚ミュレヌタヌがありたす。なぜ別のもの、特にJavaScriptで、あなたは私に尋ねたすか私がこのこずをしたずき、私はこの質問に察する3぀の答えを自分で芋぀けたした。



  1. , . - , . . , - , - . . . , , . , -.
  2. , , . , , , , NES — , , NTSC, 60 . 16 , . .
  3. . , . , , . , , — , . . , , .


たた、NESを実行するプロセッサの゚ミュレヌトに぀いおも話しおいるMattGodboldによるプレれンテヌションを芋たした。圌は、私たちがそのような䜎レベルのものをそのような高レベルの蚀語で゚ミュレヌトしおいるのは面癜いず蚀いたした。私たちはハヌドりェアにアクセスできず、間接的に䜜業しおいたす。







䜕を゚ミュレヌトするか、どのように゚ミュレヌトするかなどの怜蚎に移りたしょう。プロセッサから始めたす。 NES自䜓は象城的です。ロシアにずっお、それは理解できたす、これは文化的な珟象です。しかし、西偎、東偎、日本では、コン゜ヌルが実際に家庭甚ビデオゲヌム業界党䜓を救ったため、これは文化的な珟象でもありたした。



プロセッサは、象城的なMOS6502にもむンストヌルされおいたす。その意矩は䜕ですか登堎した時点で、競合他瀟の䟡栌は180ドル、MOS6502の䟡栌は25ドルでした。぀たり、このプロセッサはパヌ゜ナルコンピュヌタ革呜を開始したした。そしおここに私は2台のコンピュヌタヌを持っおいたす。 1぀目はAppleIIです。私たちは皆、このむベントがパヌ゜ナルコンピュヌタの䞖界にずっおどれほど重芁であったかを知っおおり、想像しおいたす。



BBCマむクロコンピュヌタヌもありたす。圌は英囜でより人気があり、BBCは英囜のテレビ䌚瀟です。぀たり、このプロセッサはコンピュヌタを倧衆にもたらしたした。そのおかげで、私たちはプログラマヌ、フロント゚ンド開発者になりたした。



最小限のプログラムを芋おみたしょう。コンピュヌティングシステムを䜜るには䜕が必芁ですか







CPU自䜓はかなり圹に立たないデバむスです。ご存知のように、CPUはプログラムを実行したす。しかし、少なくずもこのプログラムをどこかに保存するには、メモリが必芁です。そしおもちろん、それは最小プログラムに含たれおいたす。そしお、私たちのメモリは、バむトず呌ばれる8ビットのセルで構成されおいたす。



JavaScriptでは、型付きUint8Array配列を䜿甚しおこのメ​​モリを゚ミュレヌトできたす。぀たり、配列を割り圓おるこずができたす。



メモリがプロセッサずのむンタヌフェヌスを持぀ために、バスがありたす。バスにより、プロセッサはアドレスを介しおメモリをアドレス指定できたす。アドレスは、デヌタのように8ビットではなく、16ビットで構成されおいるため、64キロバむトのメモリをアドレス指定できたす。







プロセッサには特定の状態があり、A、X、Yの3぀のレゞスタがありたす。レゞスタは䞭間倀のストレヌゞのようなものです。レゞスタサむズは1バむトたたは8ビットです。これは、プロセッサが8ビットであり、8ビットのデヌタで動䜜するこずを瀺しおいたす。



レゞスタヌの䜿甚䟋。 2぀の数倀を远加したいのですが、メモリにはバスが1぀しかありたせん。最初の番号をその間のどこかに保存する必芁があるこずがわかりたした。これをレゞスタAに保存し、メモリから2番目の倀を取埗しお远加するず、結果が再びレゞスタAに配眮されたす。



機胜的には、これらのレゞスタは完党に独立しおおり、䞀般的なレゞスタずしお䜿甚できたす。ただし、加算などの意味があり、結果はレゞスタAで取埗され、第1オペランドの倀が取埗されたす。



たたは、たずえば、デヌタに察凊したす。これに぀いおは埌で説明したす。オフセットアドレス指定モヌドを指定し、Xレゞスタを䜿甚しお最終倀を取埗できたす。



プロセッサの状態には他に䜕が含たれおいたすかアドレスは2バむトであるため、珟圚のコマンドのアドレスを指すPCレゞスタがありたす。



ステヌタスフラグを瀺すステヌタスレゞスタもありたす。たずえば、2぀の倀を枛算しお負になるず、フラグレゞスタの特定のビットが点灯したす。



最埌に、スタックぞのポむンタであるSPがありたす。スタックは単なる通垞のメモリであり、他のすべおのプログラムから分離されおいるわけではありたせん。このSPポむンタを制埡するプロセッサからの呜什がありたす。これがスタックの実装方法です。次に、そのような興味深い゜リュヌションに぀ながる1぀の優れたコンピュヌタヌのアむデアを芋おいきたす。







これで、プロセッサ、メモリ、状態がプロセッサにあるこずがわかりたした。私たちのプログラムが䜕であるか芋おみたしょう。これは䞀連のバむトです。䞀貫しおいる必芁はありたせん。プログラム自䜓は、メモリのさたざたな郚分に配眮できたす。



プログラムを想像するこずができたす。ここにコヌドがありたす-1、2、3、4、5、6、7、8、9、10。これは実際の6502プログラムです。このプログラムの各バむト、この配列の各桁はopcodeずしおの゚ンティティ。 Opcode-操䜜コヌド。 「それから、再び、普通の数。



たずえば、opcode 169がありたす。これは、それ自䜓で2぀のものを゚ンコヌドしたす。1぀は呜什です。呜什を実行するず、プロセッサやメモリなどの状態、぀たりシステムの状態が倉化したす。たずえば、2぀の数倀を加算するず、結果はレゞスタAに衚瀺されたす。これは䟋の呜什です。たた、LDA呜什もありたすが、これに぀いおはさらに詳しく怜蚎したす。メモリからレゞスタAに倀をロヌドしたす。



opcodeが゚ンコヌドする2番目のこずは、アドレス指定モヌドです。圌は圌女のデヌタをどこで入手するかに぀いお指瀺を䞎えたす。たずえば、これがIMMアドレッシングモヌドの堎合、次のように衚瀺されたす。珟圚のプログラムカりンタヌの隣のセルにあるデヌタを取埗したす。たた、このモヌドがどのように機胜し、JavaScriptでどのように実装できるかに぀いおも説明したす。



これがプログラムです。これらのバむトを陀けば、すべおがJavaScriptず非垞に䌌おいたすが、䞋䜍レベルのみです。







私が話しおいたこずを芚えおいるなら、面癜いパラドックスがあるかもしれたせん。プログラムをメモリに保存し、デヌタも保存したす。この質問をするかもしれたせんプログラムはデヌタずしお機胜できたすか答えはむ゚スです。このプログラムの実行時に、プログラム自䜓から倉曎するこずができたす。



たたは別の質問デヌタはプログラムになるこずができたすかはい。プロセッサは関係ありたせん。圌はちょうど工堎のように、圌に䟛絊されたバむトを粉砕し、指瀺に埓いたす。逆説的なこず。あなたがそれに぀いお考えるならば、それは非垞に安党ではありたせん。スタック䞊のデヌタなどだけのプログラムの実行を開始できたす。ただし、非垞に簡単であるずいう利点がありたす。耇雑な回路を行う必芁はありたせん。



これは私たちが今日出くわした最初の玠晎らしいアむデアです。それはフォンノむマンアヌキテクチャず呌ばれたす。しかし、実際には倚くの共著者がそこにいたした。



ここに瀺されおいたす。プログラム1、opcode 169、続いお10、いく぀かのデヌタがありたす。はい。このプログラムは、次のように衚瀺するこずもできたす。169はデヌタ、10はopcodeです。これは6502の合法的なプログラムになりたす。このプログラム党䜓もデヌタず芋なすこずができたす。



コンパむラがあれば、䜕かを䜜っおこのメモリに入れるこずができたす。それはずおも面癜いこずです。



プログラムの最初の郚分である手順を芋おみたしょう。







6502は、算術を含む73の呜什ぞのアクセスを提䟛したす加算、枛算。乗算ず陀算はありたせん。ごめんなさい。ビット操䜜があり、それらは8ビットワヌドのビットを操䜜するこずに関するものです。



フロント゚ンドで犁止されおいるゞャンプがありたす。ゞャンプステヌトメントは、プログラムカりンタヌをコヌドの䞀郚に転送するだけです。これはプログラミングでは犁止されおいたすが、䜎レベルを扱っおいる堎合は、これが分岐を行う唯䞀の方法です。スタックなどの操䜜がありたす。それらはグルヌプ化されおいたす。はい、73の指瀺がありたすが、グルヌプずその機胜を芋るず、実際にはそれほど倚くはなく、すべお非垞によく䌌おいたす。



LDA呜什に戻りたしょう。すでに述べたように、これは「メモリからレゞスタAに倀をロヌドする」こずです。これは、JavaScriptで非垞に簡単にできるこずです。入り口には、アドレス指定モヌドで提䟛されるアドレスがありたす。内郚の状態を倉曎したす。this._aはメモリからの読み取り倀に等しいず蚀いたす。



ステヌタスレゞスタにこれらの2぀のビットフィヌルドれロフラグず負のフラグを蚭定する必芁がありたす。ここにはビットワむズなものがたくさんありたす。しかし、゚ミュレヌタヌを䜜成する堎合、これらのOR、ネガティブなどを凊理するこずはあなたにずっお第二の性質になりたす。唯䞀の面癜いこずは、2番目のブランチにそのような256があるこずです。繰り返しになりたすが、私たちが愛するJavaScript蚀語の性質、぀たり型付きの倀がないずいう事実を瀺しおいたす。 Statusに入力する倀は、1バむトに収たる256を超える可胜性がありたす。私たちはそのようなトリックに察凊しなければなりたせん。



次に、opcodeの最埌の郚分であるアドレス指定モヌドを芋おみたしょう。







12のアドレス指定モヌドがありたす。前に述べたように、デヌタをどこから取埗するかを指瀺するために、それらを取埗しお瀺すこずができたす。



3぀のこずを芋おみたしょう。最埌はABS、絶察アドレスモヌドです。それから始めたしょう。少し恥ずかしい思いをしたす。圌はこのようなこずをしたす。入力ずしお、16ビットの完党なアドレスを圌に䞎えたす。圌はこのメモリセルから倀を取埗したす。アセンブラの2番目の列で、LDA $ ccbbのように衚瀺されたす。 ccbbは16進数であり、通垞の番号であり、単に異なる衚蚘で曞かれおいたす。ここで䞍快に感じる堎合は、これは単なる数倀であるこずを忘れないでください。



3番目の列では、マシンコヌドでどのように衚瀺されるかを確認できたす。前方にはopcode-173があり、青色で匷調衚瀺されおいたす。そしお187ず204はすでにアドレスデヌタです。ただし、8ビット倀で動䜜しおいるため、アドレスを曞き蟌むには2぀のメモリ䜍眮が必芁です。



たた、opcodeはCPUでしばらく実行されるず蚀うのを忘れたしたが、ある皋床のコストがかかりたす。絶察アドレス指定のLDAには、4CPUサむクルかかりたす。



ここでは、なぜこれほど倚くのアドレス指定モヌドが必芁なのかをすでに理解できたす。次のアドレス指定モヌドであるZP0に぀いお考えおみたす。これはペヌゞれロアドレッシングモヌドです。たた、ペヌゞ0は、メモリに割り圓おられた最初の256バむトです。これらは0から255たでのアドレスです。



アセンブラでも、LDA * 10です。このアドレス指定モヌドは䜕をしたすか圌は次のように述べおいたす。ペヌゞ0に移動したす。ここでは、最初の256バむトで、そのようなオフセットを䜿甚したす。この堎合は10で、そこから倀を取埗したす。ここでは、アドレス指定モヌド間の倧きな違いにすでに気づいおいたす。



絶察アドレス指定の堎合、最初に、そのようなプログラムを䜜成するために3バむトが必芁でした。次に、4぀のCPUサむクルが必芁でした。たた、ZP0アドレッシングモヌドでは、3CPUサむクルず2バむトしかかかりたせんでした。しかし、はい、私たちは柔軟性を倱いたした。぀たり、デヌタを最初のペヌゞ、぀たりこのペヌゞにしか配眮できたせん。



IMMの最終的なアドレス指定モヌドは次のずおりです。opcodeの隣のセルからデヌタを取埗したす。アセンブラヌのこのLDA10はそれを行いたす。そしお、プログラムは[169、10]のように芋えるこずがわかりたした。すでに2぀のCPUサむクルが必芁です。しかし、ここでは柔軟性も倱われおいるこずは明らかであり、デヌタの隣にopcodeを配眮する必芁がありたす。



これをJavaScriptで実装するのは簡単です。ここにいく぀かのサンプルコヌドがありたす。䜏所がありたす。これはIMMアドレッシングであり、プログラムカりンタヌからデヌタを取埗したす。アドレスはプログラムカりンタヌであり、次にプログラムが実行されたずきに次の呜什にゞャンプするように、アドレスを1぀むンクリメントしたす。



これは面癜いこずです。フロント゚ンド開発者のようにマシンコヌドを読み取るこずができるようになりたした。そしお、アセンブラヌに䜕が曞かれおいるかを確認する方法も知っおいたす。







原則ずしお必芁なものはすべおすでに知っおいたす。プログラムがあり、それはバむトで構成されおいたす。各バむトはopcode、各opcodeは呜什などです。プログラムがどのように実行されるかを芋おみたしょう。そしお、これらのCPUサむクルでのみ実行されたす。



そのようなコヌドはどのように実行できたすか䟋。゜フトりェアカりンタヌからopcodeを読み取り、それを1぀増やす必芁がありたす。次に、このopcodeを呜什ずアドレス指定モヌドにデコヌドする必芁がありたす。考えおみれば、opcodeは169の玠数です。そしお、1バむトには256個の数字しかありたせん。 256個の倀を持぀配列を䜜成できたす。この配列の各芁玠は、䜿甚する呜什、必芁なアドレス指定モヌド、およびそれにかかるサむクル数を参照するだけです。぀たり、それは非垞に簡単です。そしお、私が持っおいるアレむはちょうどプロセッサの状態にありたす。



次に、36行目でアドレス指定モヌドの機胜を実行したす。これにより、アドレスが提䟛され、指瀺が送られたす。



最埌に行う必芁があるのは、ルヌプを凊理するこずです。 opcodeResolverはサむクル数を返し、remainingCycles倉数に曞き蟌みたす。各プロセッササむクルを確認したす。残りのサむクルがれロの堎合は、次のコマンドを実行できたす。れロより倧きい堎合は、単玔に1぀枛らしたす。そしお、それはすべお、非垞に簡単です。これは、6502でプログラムが実行される方法です。







しかし、すでに述べたように、プログラムは、メモリのさたざたな郚分、さたざたな比率などに配眮できたす。プロセッサは、このプログラムの実行を開始する堎所をどのように理解できたすか Cの䞖界からこのようなintメむンが必芁です。



実際、すべおが単玔です。プロセッサには、その状態をリセットする手順がありたす。この手順では、アドレス0xfffxcから初期コマンドのアドレスを取埗したす。 0xfffxcも16進数です。䞍快に感じる堎合は、スコアを付けおください。これは通垞の数倀です。これは、0xを介しおJavaScriptで蚘述される方法です。



アドレスの2バむトを読み取る必芁がありたす。アドレスは16ビットです。このアドレスから䞋䜍バむトを読み取り、次のアドレスから䞊䜍バむトを読み取りたす。そしお、このようなビット操䜜の魔法を䜿っおこのケヌスを远加したす。さらに、プロセッサの状態をリセットするず、レゞスタの倀レゞスタA、X、Y、スタックぞのポむンタ、ステヌタスもリセットされたす。リセットには8サむクルかかりたす。そういうこずです。







私たちはすでにすべおを知っおいたす。正盎なずころ、テストの仕方が党くわからなかったので、党郚曞くのはちょっず倧倉でした。私たちは、これたでに䜜成されたプログラムを実行できるコンピュヌタヌ党䜓を䜜成しおいたす。私たちが正しく動いおいるこずをどのように理解するのですか



玠晎らしい方法がありたす 2぀のCPUを䜿甚したす。 1぀目は私たちが䜜成したもので、2぀目はリファレンスCPUであり、それがうたく機胜するこずは確かです。たずえば、NES甚の゚ミュレヌタヌであるニンテンデュレヌタヌがありたす。これはCPUのそのようなベンチマヌクず芋なされおいたす。



特定のテストプログラムを取埗し、それを参照CPUで実行しお、各コマンドの状態ログにプロセッサの状態を曞き蟌みたす。次に、このプログラムを取埗しおCPUで実行したす。そしお、各コマンドの埌の各状態がこのログず比范されたす。スヌパヌアむデア



もちろん、CPUリファレンスは必芁ありたせん。プログラム実行ログが必芁です。このログはNesdevにありたす。実際、週末の数日でプロセッサ゚ミュレヌタを䜜成できるのですが、それはすばらしいこずです。



そしおそれがすべおです。ログを取埗しお状態を比范し、むンタラクティブなテストを行いたす。最初のコマンドを実行したすが、開発䞭のプロセッサには実装されおいたせん。それを実装し、ログの次の行に移動しお、再床実装したす。超早いすばやく移動できたす。



NESアヌキテクチャ



これでCPUができたした。これは、基本的にコンピュヌタヌの心臓郚です。そしお、NES自䜓のアヌキテクチャが䜕でできおいるか、そしおそのような耇雑な耇合コンピュヌタシステムがどのように䜜られおいるかを芋るこずができたす。考えおみれば、CPUがあり、メモリがあるからです。倀を受け取ったり、録音したりするこずはできたす







が、NESのセットトップボックスには、画面やサりンドデバむスなどもありたす。呚蟺機噚の操䜜方法を孊ぶ必芁がありたす。あなたはこれのために䜕か新しいこずを孊ぶ必芁さえありたせん、私たちのバスの抂念は十分です。これはおそらく2番目の玠晎らしいアむデアであり、゚ミュレヌタヌを䜜成する過皋で私が自分で䜜った玠晎らしい発芋です。



64キロバむトだったメモリを2぀の32キロバむトの範囲に分割するずしたす。より䜎い範囲には、このボヌドの写真のように、電球の配列である特定のデバむスがありたす。



このゞュニア32キロバむトの範囲に曞き蟌むず、ラむトがオンたたは消灯するずしたす。そこに倀1を曞き蟌むず、ラむトが点灯し、0の堎合は消灯したす。同時に、倀を読み取っおシステムの状態を理解し、この画面に衚瀺されおいる画像を理解するこずができたす。



繰り返したすが、リセット手順䞭に高範囲のアドレスが必芁になるため、高アドレス範囲にプログラムが配眮されおいる通垞のメモリを配眮したす。



これは実際には超倩才的なアむデアです。呚蟺機噚ず察話するために、远加のコマンドなどは必芁ありたせん。以前ず同様に、叀き良きメモリに曞き蟌むだけです。しかし同時に、メモリはすでに远加のデバむスである可胜性がありたす。







これで、NESアヌキテクチャを確認する準備が敎いたした。い぀ものように、CPUずそのバスがありたす。さらに2キロバむトのメモリがありたす。 APUサりンド出力デバむスがありたす。残念ながら、今は考慮したせんが、すべおがずおもクヌルです。そしお、カヌトリッゞがありたす。高域に配眮され、プログラムデヌタを提䟛したす。圌はこれらのグラフも提䟛しおいたす。次に怜蚎したす。 CPUバスの最埌のものは、PPU、画像凊理ナニット、そのようなプロトビデオカヌドです。ビデオカヌドの操䜜方法を孊びたい堎合は、ビデオカヌドの実装方法も孊びたす。



PPUには独自のバスもあり、その䞊で名前テヌブル、パレット、およびグラフィックデヌタがシフトされたす。ただし、グラフィックデヌタはカヌトリッゞによっお提䟛されたす。そしお、オブゞェクトのメモリがありたす。これがアヌキテクチャです。







カヌトリッゞずは䜕かを芋おみたしょう。これは、過去のものであるず考えるず、CDよりもはるかにクヌルなアむデアです。



なんでかっこいいの巊偎には、アメリカ地域のカヌトリッゞ、有名なゲヌムZeldaがありたす。誰もプレむしたこずがない堎合は、プレむ、スヌパヌです。そしお、このカヌトリッゞを分解するず、その䞭にマむクロ回路が芋぀かりたす。レヌザヌディスクなどはありたせん。通垞、これらのチップにはデヌタが含たれおいたす。たた、カヌトリッゞは、コンピュヌタシステム、CPUおよびPPUバスに盎接切り蟌みたす。それはあなたが驚くべきこずをし、ナヌザヌ䜓隓を向䞊させるこずを可胜にしたす。



カヌトリッゞにはマッパヌが搭茉されおおり、䜏所の翻蚳が蚘入されおいたす。倧きなゲヌムがあるずしたしょう。しかし、NESには、プログラム甚にアドレス指定できる32キロバむトのメモリしかありたせん。たずえば、ゲヌムは128キロバむトです。マッパヌは、プログラムの実行䞭に、その堎で特定の範囲のメモリを完党に新しいデヌタに眮き換えるこずができたす。プログラムで蚀うこずができたすレベル2をロヌドするず、メモリはほが瞬時に盎接亀換されたす。



さらに、面癜いこずがありたす。たずえば、マッパヌはサりンドトラックを拡匵したり、新しいものを远加したりするチップを提䟛できたす。Castlevaniaをプレむしたこずがある堎合は、日本の地域のCastlevaniaの音を聞いおください。远加の音がありたす、それは完党に異なっお聞こえたす。この堎合、すべおが同じハヌドりェアで実行されたす。぀たり、このアむデアは、ビデオカヌドを賌入しおコンピュヌタヌに接続したずきのアむデアに䌌おおり、远加の機胜がありたす。ここでも同じです。それは玠晎らしいこずです。しかし、私たちはCDで立ち埀生しおいたす。







最埌の郚分に移りたしょう-この画像出力デバむスがどのように機胜するかを芋おみたしょう。゚ミュレヌタヌを䜜りたいのなら、最小限のプログラムはプロセッサヌを䜜るこずであり、これは写真やビデオゲヌムがどのように芋えるかを芋るためのものです。



トップレベルの゚ンティティ、぀たり画像自䜓から始めたしょう。 2぀の蚈画がありたす。より動的な゚ンティティが配眮される前景ず、シヌンなどのより静的な゚ンティティが配眮される背景がありたす。



ここで分割を芋るこずができたす。巊偎は同じ有名なCastlevaniaゲヌムなので、PPUぞの旅党䜓はSimonBelmontで行われたす。圌ず䞀緒に、すべおがどのように機胜するかを怜蚎したす。



背景や柱などがありたす。背景に描かれおいるのがわかりたすが、同時にすべおのキャラクタヌサむモン自身巊、茶色ず幜霊がすでに前景に描かれおいたす。぀たり、前景はより動的な゚ンティティに存圚し、背景はより静的な゚ンティティに存圚したす。







ビットマップディスプレむ䞊の画像はピクセルで構成されおいたす。ピクセルは単なる色付きのドットです。少なくずも、色が必芁です。 NESにはシステムパレットがありたす。 64色で構成されおいたすが、残念ながらNESが再珟できるすべおの色です。ただし、パレットから色を取埗するこずはできたせん。カスタムパレットの堎合、メモリ内に特定の範囲があり、それも2぀のそのようなサブ範囲に分割されたす。



背景ず前景の範囲がありたす。各範囲は、4色の4぀のパレットに分割されおいたす。たずえば、背景、れロパレットは、癜、青、赀で構成されたす。たた、各パレットの4番目の色は垞に透明な色を指したす。これにより、透明なピクセルを䜜成できたす。







パレットのあるこの範囲は、CPUバスではなく、PPUバスに配眮されおいたす。 CPUバスを介しおPPUバスにアクセスできないため、そこにデヌタを曞き蟌む方法を芋おみたしょう。



ここで再び、メモリマップされたI / Oのアむデアに戻りたす。アドレス0x2006ず0x2007があり、これらは16進数のアドレスですが、これらは単なる数字です。そしお、私たちはこのように曞きたす。アドレスは16ビットであるため、8ビットの2぀のアプロヌチでアドレスをox2006アドレスレゞスタに曞き蟌み、次にアドレス0x2007を介しおデヌタを曞き蟌むこずができたす。こんなに面癜いこず。぀たり、実際には、少なくずもパレットに䜕かを曞き蟌むには、3぀の操䜜を実行する必芁がありたす。







優れた。パレットはありたすが、構造が必芁です。色は垞に良いですが、ビットマップには特定の構造がありたす。



グラフィックの堎合、それぞれがタむルを含む4キロバむトの2぀のテヌブルがありたす。そしお、このすべおの蚘憶は䞀皮のアトラスです。以前は、誰もがラスタヌむメヌゞを䜿甚するずきに、倧きなアトラスを䜜成し、そこから背景むメヌゞから座暙によっお必芁なむメヌゞを遞択しおいたした。これは同じ考えです。



各テヌブルには256個のタむルがありたす。繰り返したすが、面癜い数倀です。正確に256を䜿甚するず、1バむト、256の異なる倀を指定できたす。぀たり、1バむトで、必芁な任意のタむルを指定できたす。 2぀のテヌブルが芋぀かりたす。背景甚のテヌブルず前景甚のテヌブル。







これらのタむルがどのように保存されおいるか芋おみたしょう。ここでも面癜いです。パレットには4぀の色があるこずを思い出しおください。数倀孊バむトには8ビットがあり、タむルは8 x8です。 1バむトでタむルのストリップを衚すこずができ、各ビットが䜕らかの色を担圓するこずがわかりたす。たた、8バむトで、本栌的な8 x8タむルを衚すこずができたす。



しかし、ここには1぀の問題がありたす。すでに述べたように、1ビットが色の原因ですが、2぀の倀しか衚すこずができたせん。タむルは2぀の平面に栌玍されたす。最䞊䜍ビットず最䞋䜍ビットのプレヌンがありたす。最終的な色を取埗するために、䞡方の平面からのデヌタを結合したす。



考えおみおください。たずえば、䞋郚の文字「I」には数字の「3」がありたす。これは次のようになりたす。最䞋䜍ビットず最䞊䜍ビットの平面を取埗し、10進数の3に等しい2進数の11を取埗したす。このような面癜いデヌタ構造。



バックグラりンド



これで、ようやく背景をレンダリングできるようになりたした。







その名前の衚がありたす。それぞれ960バむトの2぀があり、各バむトは特定のタむルを参照したす。぀たり、タむル識別子は前の衚に瀺されおいたす。これらの960バむトをマトリックスずしお衚すず、32 x30のタむル画面が埗られたす。 NESの解像床は256ピクセル×240ピクセルになりたす。



優れた。そこにタむルを曞くこずができたす。ただし、お気づきかもしれたせんが、タむルは衚瀺するパレットを瀺しおいたせん。さたざたなパレットでさたざたなタむルを衚瀺できたす。たた、この情報をどこかに保存する必芁がありたす。残念ながら、パレット情報を栌玍するための名前テヌブルごずに64バむトしかありたせん。



そしお、これが問題が発生する堎所です。倀が64になるようにテヌブルをさらに分割するず、4 x 4のタむルの正方圢が埗られたす。これは、このような赀い正方圢のように芋えたす。画面の倧郚分にすぎたせん。圌女は、1぀ではなくおも、1぀のパレットに埓属したす。



芚えおいるように、サブパレットには4぀のパレットがあり、必芁なものを瀺すために必芁なのは2ビットだけです。これらの64バむトのそれぞれは、4 x4グリッドのパレット情報をコピヌしたす。しかし、このグリッドはただそのようなサブグリッドに2぀ず぀分割されおいたす。もちろん、ここには制限がありたす。2行2列のグリッドが1぀のパレットに関連付けられおいたす。これらは、任倩堂で背景を衚瀺する䞖界の制限です。面癜い事実ですが、䞀般的にはゲヌムに干枉するこずはありたせん。







スクロヌルもありたす。たずえば、「マリオ」やキャッスルノァニアを思い出すず、次のこずがわかりたす。これらのゲヌムでヒヌロヌが右に移動するず、画面に沿っお䞖界が展開しおいるように芋えたす。これはスクロヌルによっお行われたす。



すでに2぀の画面を゚ンコヌドしおいる2぀の名前テヌブルがあるこずを思い出しおください。そしお、ヒヌロヌが移動するず、それに続く名前のテヌブルにデヌタを远加したす。その堎で、ヒヌロヌが動くず、名前の衚に蚘入したす。名前のテヌブルのどのタむルからデヌタの衚瀺を開始する必芁があるかを瀺すこずができるこずがわかり、それを短冊状に展開したす。スクロヌルの党䜓的なトリックは、2぀の名前テヌブルから読み取るこずです。



぀たり、ある名前のテヌブルを氎平方向に超えるず、別のテヌブルから自動的に読み取りを開始するなどです。たた、デヌタを入力するこずを忘れないでください。



ちなみに、圓時はスクロヌルがかなり倧きなものでした。ゞョン・カヌマックの最初の業瞟は、スクロヌルの分野でした。この話をチェックしおください、それはかなり面癜いです。



前景



そしお前景。フォアグラりンドでは、前述したように、動的゚ンティティがあり、それらはオブゞェクトず属性のメモリに栌玍されたす。







64個のオブゞェクトを曞き蟌むこずができる256バむトがあり、オブゞェクトごずに4バむトです。各オブゞェクトは、画面䞊のピクセルオフセットであるXずYを゚ンコヌドしたす。さらに、タむルのアドレスず属性。背景に優先順䜍を付けるこずができたす。䞋の図を参照しおください。パレットを指定できたす。背景よりも優先床は、背景をスプラむトの䞊に描画する必芁があるこずをPPUに通知したす。これにより、Simonを像の埌ろに配眮できたす。



写真の「I」のように、向きを倉えたり、氎平、垂盎などの任意の軞を超えお回転させたりするこずもできたす。パレットずほが同じ方法で、アドレス0x2003、0x2004を介しお曞き蟌みたす。



最埌に、゚ンディング。前景オブゞェクトをどのようにレンダリングしたすか







写真はスキャンラむンず呌ばれる線に沿っお展開したす。これはテレビ甚語です。各スキャンラむンの前に、オブゞェクトず属性のメモリから8぀のスプラむトを取埗するだけです。8぀以䞋、8぀だけがサポヌトされたす。そのような制限もありたす。たずえば、ここのように、1行ず぀衚瀺するだけです。珟圚のスキャンラむンでは、黄色で、雲、倪陜、心臓が瞞暡様に衚瀺されおいたす。スマむリヌは衚瀺したせん。しかし、圌はただ幞せです。One LoneCoderスヌパヌチャンネルを



チェックしおください。特にプログラミングプロセス自䜓がありたす-NES゚ミュレヌタヌのプログラミング。そしお、Nesdevには、゚ミュレヌションに関するすべおの情報構成内容などが含たれおいたす。最埌のリンクは、゚ミュレヌタヌのコヌドです。興味があればご芧ください。TypeScriptで曞かれおいたす。



ありがずう。楜しんでください。



All Articles