PlayStationアーキテクチャ
(copetti.org)- PlayStationアーキテクチャは、3Dハードウェア開発の複雑さを減らすために単純で実用的な構成を採用したが、その代償として、グラフィックの整列・テクスチャ補正・精度の面で開発者の負担と視覚的な限界を残した
- Sony CXD8530BQは、LSI LogicのCoreWareベースのMIPS R3000A互換コアとCP0、GTE、MDECを統合したSoCであり、33.87MHzで動作し、2MB RAM・1KB Scratchpad・DMAを中心にデータ移動を構成する
- グラフィックスは、GTEが3D投影・ライティング・クリッピングを担当し、GPUが命令ベースで線・四角形・三角形をレンダリングする構造であり、Z-bufferなしでordering tableを使うため、CPUがポリゴンの順序を決めなければならない方式である
- GPUはaffine texture mapping、nearest neighbour、整数座標、サブピクセル解像度の欠如により、揺れ・重なり・texture warpingが発生し、tessellation・単色置換・pre-rendered背景のような回避策が活用された
- CD-ROMベースの設計は、620MBの保存容量、44.1kHz ADPCMオーディオストリーミング、BIOSベースの実行環境、Wobble Grooveによるコピー防止とリージョンロックを組み合わせ、ゲーム開発と配布の方式を変えた
基本設計とCPU
- PlayStationは、3Dハードウェアが開発上複雑になり得るという前提から、単純で実用的な設計を志向しており、その代償としていくつかの制約を受け入れる構造になっている
- メインチップのSony CXD8530BQは、今日の表現で言えばSoCに相当し、MIPS R3000A系とバイナリ互換のLSI Logic製CoreWareベースCPUコアを使用している
- CPUコアは33.87MHz、MIPS I ISA、32ビットワード、32本の汎用レジスタ、32ビットデータバス、32ビットアドレスバス、5段パイプライン、4KB命令キャッシュを備える
- データキャッシュはなく、本来データキャッシュに相当する1KBメモリは固定アドレスにマップされたScratchpadとして提供され、高速なSRAMのように使われる
- システムは汎用作業向けに2MB EDO RAMを提供し、EDO RAMは通常のDRAMよりやや効率的で低レイテンシなチップとして説明される
バスと補助プロセッサ
- データバスは32ビットのMain Busと16/8ビットのSub Busに分かれており、Main BusはMDECとGPUを接続し、Sub Busはその他の構成要素とI/Oを接続する
- CD-ROM controller、MDEC、GPU、SPU、parallel portはDMA controllerにアクセスでき、DMAはCPUを経由せずメインバスを占有して高いスループットでデータを転送する
- DMA動作中、CPUはメインバスにアクセスできず、Scratchpadに処理すべき作業がなければ待機状態になる構造である
- CP0であるSystem Control Coprocessorは、キャッシュ実装、Scratchpadへの直接アクセス、命令キャッシュ隔離、割り込み、例外、breakpointを管理する
- CP2であるGeometry Transformation Engineは、固定小数点ベースのベクトル・行列計算を高速化し、3D投影、ライティング、クリッピングなどグラフィックスパイプラインの初期段階を担う
- MDECはJPEGに似た形式でエンコードされたmacroblockを、GPUが理解できる形式へ展開し、8×8ピクセル24bppビットマップを毎秒9,000 macroblock処理して320×240pxのFMVを30fpsでストリーミングできる
- CP1に相当するFPUは搭載されておらず、小数計算はソフトウェア浮動小数点または固定小数点で処理できるが、速度や精度に制約が生じる
パイプラインと遅延スロット
- MIPS Iパイプラインはcontrol hazardとdata hazardに弱く、branch・jumpの次の命令が必ず実行されるbranch delay slotの動作を持つ
- load命令は、読み込んだデータの準備が整うまでパイプラインを停止しないため、直後の命令が直前のload結果に依存する場合、正しいオペランドを得るためにfillerが必要になる
- 一部のdelay slotは意味のある命令で埋められるため、常に無駄なサイクルになるわけではない
- MIPSは、高品質なコンパイラとアセンブラが命令の再配置やfiller挿入を処理するというRISC哲学に基づき、CPUパイプラインを開発者とツールチェーンに露出する設計を採用した
- この設計は、後続CPU世代で新しいマイクロアーキテクチャが登場するほど下位互換性を難しくする欠点も持つ
グラフィックスパイプライン
- グラフィックスパイプラインのかなりの部分をGTEが処理し、その結果データはSony独自のGPUへ渡されてレンダリングされる
- システムは1MB VRAMにframe buffer、texture、その他のレンダリング資源を保存し、CPUはDMAでこの領域を埋められる
- 初期モデルのVRAMはdual-ported構造で、2本の16ビットバスを使ってCPU、DMA、GPU、video encoderが同時にアクセスできる
- 後期モデルでは、単一の32ビットデータバスを使うSGRAMへ変更され、タイミング差のため Jet Moto 3 のような後発ゲームがVRAMベースのシステムでグラフィック破損を見せる場合がある
- CPUはGPUの64バイトFIFO bufferに最大3つの命令を詰めてジオメトリデータを送り、命令はレンダリング、設定変更、VRAM操作を要求する
- GPUは線、四角形、三角形を個別に描画でき、三角形は豊かな3Dモデルを構成する基本要素として使われる
- GPU座標系は、各座標がピクセル中心のsampling pointに対応する整数座標モデルであり、fractional coordinateは使わない
可視性、ラスタライズ、テクスチャ
- PlayStation GPUはハードウェアによるvisibility解決機能を提供せず、ordering tableを通じてdepth値ごとにGPU commandのアドレスを管理する
- CPUは先にポリゴンを並べ替え、tableの適切な項目に参照を入れた後、DMAでtableをGPUへ送り、正しい順序でレンダリングさせる
- GPUは単一のframe bufferだけを必要とし、rasteriserがvertexを線・三角形・四角形とピクセルへ変換する
- 三角形はtextureとshadingをサポートする最も複雑で汎用的なprimitiveであり、線は高速だがtexture表面には向かず、四角形は最大256×256ピクセルspriteに制限され、shadingやaffine変換効果を提供しない
- ライティング効果にはflat shadingとGouraud shadingの2種類があり、flat shadingはGouraud shadingより毎秒約2.5倍多くのポリゴンを塗りつぶせる
- textureは、rasterised pixelごとにtexture mapのtexelを参照するinverse texture mappingによって適用される
- PlayStation GPUのAffine Texture MappingはX/Yの2D座標だけを使い、depthを捨てるためperspective correctionを行わない
- texture filteringは実装されておらず、scale補正にはnearest neighbourが使われ、これは高速で低コストだが、textureモデルがblockyに見える原因になる
- GPUは三角形にsemi-transparencyとdithering効果をサポートしており、PlayStationはこれらの効果で優れていたと描写される
VRAM運用と視覚的限界
- 1MB VRAM全体を大きくframe bufferに使う構想は、TV標準フォーマットへの再調整が必要であり、texture・colour tableの空間を減らし、GPU自体も最大640×480ピクセル16ビットカラーframe bufferまでしかレンダリングできない
- 640×480の16ビットbufferは、素材用として424KBのVRAMを残すが、当時の家庭用TVでは高解像度の利点が特に際立たないという問題がある
- adjustable frame-bufferは、体感差の小さい解像度にVRAMを浪費せず、frame bufferサイズを減らしてtextureとcolour lookup tableの空間を増やす方式である
- Halkunの Gears Episode 2 デモは、640×480 frame bufferを2つの320×480 bufferに分割し、page flippingを使って一方の場面を表示している間にもう一方をレンダリングする構成を示している
- このlayoutは600KBのVRAMしか消費せず、残りの424KBをcolour lookup tableとtextureに使え、2KB texture cacheと合わせて効率的な構成になる
- VRAMは複数のcolour depthを同時にマップできるため、16bpp frame bufferの横にFMV frameでよく使われる24bpp bitmapを配置できる
- rasteriserはピクセル単位でしか処理せず、triangleがpixel fractionをどれだけ占めるかを追跡しないため、モデル外周の跳ねやtriangle交差部でのflicker・overlapが発生しうる
- ordering tableは、どのgeometryが前面にあるかを決める負担を開発者やプログラム側に委ねており、性能のために近似計算が多いとflickeringや隠面の問題が起こりうる
- affine transformationはdepth感がないため、カメラがモデルに近く視線に垂直なときtexture warpingを生じさせることがあり、一部のゲームはtessellationやsolid colour置換で歪みを減らした
- pre-rendered背景は、リアルタイムGPU表現より写実的な場面が必要なとき、MDECでストリーミングした映像を2枚の三角形に貼る方式で活用された
オーディオとCDベースゲーム
- SPUは44.1kHzのAudio CD品質の16ビットADPCM sampleを24チャンネルサポートする
- SPUはpitch modulation、frequency modulation、ADSR envelope、looping、digital reverb機能を提供する
- オーディオバッファであるSound RAMは512KB DRAMで、ゲームはsample保存用に508KBしか使えず、reverbを有効にすると利用可能容量はさらに減る
- CD controllerは、オーディオバッファやCPUの介入なしにsampleをaudio mixerへ直接送ることができ、XA encodingで圧縮されたsampleはSPUがリアルタイムにデコードできる
- CD-ROMメディアは、PS1ゲームに620MBの保存容量、豊かなオーディオ品質、2x driveの比較的高速な読み出し速度を提供した
- 1997年までに発売されたPS1 revisionは、不具合のあるCD drive laserによりFMVやAudio CDのskipが頻発することで知られ、その後のモデルではlaser unitとhousingが改良され問題が緩和された
I/O、BIOS、開発環境
- 初期のPlayStationには拡張機器用のSerialおよびParallel I/Oポートがあったが、採用率の低さとコピー防止回避への懸念から、後のrevisionで削除された
- CD subsystemは、motor・laser・RF信号を制御するDSP、Motorola 68HC05 microcontrollerと512B RAM・16KB ROMで構成されたSub-CPU、main CPUとCD subsystemの間を中継するCD Controller、32KB SRAM bufferで構成される
- Sub-CPUのROMプログラムはコピー防止手順を実装し、main CPUの意思とは無関係にこれを強制する
- 前面にはcontroller 2個とMemory Card 2枚のためのソケット4個があり、4つのslotは電気的に同一で、アドレスはハードコードされている
- システムは512KB ROMにBIOSを保存し、BIOSはstartup、user shell、I/O routineを提供する
- BIOS ROMへのアクセスは8ビットデータバスのため非常に遅く、APIはboot時にmain RAMへコピーされるKernelの形で提供され、64KBのmain RAMがPlayStation OS用に予約される
- boot過程は、BIOS ROM実行、PlayStation OSロード、splash表示、CD真贋確認、
SYSTEM.CNF確認と実行、またはshell表示の順で進む - shellは、Memory Cardセーブのコピー・削除とAudio CD再生を提供する単純なグラフィカルインターフェースである
- Sony SDKはC compilerとlibraryを含み、libraryはハードウェアアクセスのためにBIOS routineへ接続される
- スタジオ向けのDTL-H2000は、PS1内部とI/O、debugging回路を収めたdual-slot ISA cardであり、Windows 3.1または95がインストールされたPC上で動作するソフトウェアを必要とした
- ホビイスト向けのNet Yarozeは、toolkit、manual、黒いPS1 consoleを提供したが、CD driveにアクセスできないため、homebrew softwareはすべてmain RAM内に収める必要があるという制約を持っていた
コピー防止とリージョンロック
- Sonyのコピー防止は、CDのTable of Contentsに特定周波数で刻まれたWobble GrooveがあるかどうかをSub-CPUが確認する方式である
- Wobble Grooveはmastering工程で導入され、一般的なCD burnerでは複製できず、TOCはCDのLead-In領域にあり、fault toleranceのため複数回繰り返される
- game TOCにはSCEA、SCEE、SCEIのいずれかの文字列が入り、この方式はregion-lockingにも使われる
- 検査は起動時に一度だけ実行されるため、認証直後にdiscを手動で入れ替えるswap trickで回避できるが、drive損傷の危険がある
- 一部のgameはgameplay中にdriveを再初期化して検査を繰り返すことで、swap trickを防ごうとした
- ModchipはWobble Groove信号を模倣するようプログラムされた小型ボードで、consoleにはんだ付けして使われ、法的には論争があったものの非常に人気を得た
- その後のgameは、modchip、CD burner、emulatorの普及に対応して、checksum中心の独自保護手段を追加した
- SonyのLibcryptは、特定sectorのchecksumをdisc sub-channelに保存するハードウェア側の手法と、game内の各所でchecksumを取り出して他の値と混ぜて検証するソフトウェア側routineを組み合わせている
1件のコメント
Hacker Newsのコメント
同じ物理メモリにマッピングされるメモリ領域がある — https://psx-spx.consoledev.net/memorymap/
PSXからPCへMetal Gear Solidの移植をしたのだが、KonamiのプログラマーたちはC4爆弾が壁に設置されたのか床に設置されたのかを保存するために、かなり過激なトリックを使っていた
要するにポインタは同じ物理メモリアドレスを指すのだが、壁や床に設置された場合に
80000000hと OR したりA0000000hを使ったりする形だったと思う。かなり昔のことなので正確に何をしていたのかはもうよく覚えていないが、PCへの移植作業は面白かったBIOSコードに欠陥のある配列イテレータがあり、基準ポインタよりメモリマップ上位の位置へ任意データをコピーできる。通常は基準ポインタが非常に高い場所にあるため実行コードを上書きできないが、メモリエイリアスのため値をうまく合わせると書き込みが「回り込んで」BIOSを上書きできる
そのため実質的にはメモリーカード画面に入るだけでカスタムBIOSをブートでき、そこから mechacon のチェックを通さずに PSX.EXE を実行してコピー防止を回避できる
MGSの移植についてももっと知りたい。何か覚えていることがあるのか気になる。スクリプト処理の大半に TCL を使っていた記憶があり、MGS 1〜4 が同系統のスクリプト言語を使っていたように思う
最近 MGS2 のソースコードが流出したが、おそらくほぼ全面的な書き直しに近く、PSXのコードベースと共有していた部分はほとんどなかったのではないかと思う
PS1でも RAM 全体のデコード窓を覆うほど RAM が十分でなかったため、RAMエイリアスが生じる。詳しい仕組みは分からないが、PS1実行ファイルがスタックポインタを開発キットの 8MiB RAM の終端に設定しても、リテール機では結局 2MiB RAM の終端に落ちて正常動作するのを見たことがある。理論上はそこにもビットを入れられるし、キャッシュ動作が異なるメモリ領域を触らなくても済む
https://github.com/FoxdieTeam/mgs_reversing/blob/master/sour...
https://en.wikipedia.org/wiki/Classic_Mac_OS_memory_manageme...
その結果、一部のモデルにはPCのA20ゲートとそれほど変わらない下位互換モードが生まれたが、その期間は短かった
Arm Top Byte Ignore(TBI)、Intel Linear-Address Masking(LAM) とその修正版である Linear Address Space Separation(LASS)、AMD Upper Address Ignore(UAI) があり、UAI はまだ SLAM 攻撃に対して安全ではない。その上に ARM Memory Tagging Extension(MTE) のようなセキュリティ拡張もある
素晴らしい記事だが、もともとは2019年に公開されたものだ。以前の議論は2020年の https://news.ycombinator.com/item?id=22932134 と2021年の https://news.ycombinator.com/item?id=27576902 にあり、それぞれ114件のコメントが付いている
本当に美しく設計されたウェブサイトだ。すべてが思慮深く配置されていて、よくキュレーションされたデジタルガーデンの好例のように見える。きちんと手入れされ、人が直接作った感じが強い
今PS1関連のプロジェクトに取り組んでいて、近いうちに公開したいのでこの記事を投稿した
PS1のWeb/JS/WASMエミュレータでおすすめがあれば知りたい。デスクトップでは PCSX-Redux [0] と DuckStation [1] が良かった
JS/emscripten ベースの試みはいくつか見つけたが、おすすめがあればありがたい
[0] https://github.com/grumpycoders/pcsx-redux/
[1] https://duckstation.org/
PS1はRISC、より正確にはロードストアアーキテクチャを好きになったきっかけの構造であり、x86について自分が誤って考えていたことに気づかせてくれたアーキテクチャでもあった
PS1アーキテクチャは魅力的だ。PS1ゲームがなぜ今でも再現しようとされる独特で見分けやすいスタイルを持つのかも示している
Copettiの記事が好きだ。扱っている内容をすべてよく知っているわけではないが、文章やダイアグラムを眺めるだけでも楽しい
特に第5世代や第6世代コンソールのようなマシンの内部で何が起きているのか理解しようとする過程が面白い
https://fabiensanglard.net/
Claude以前に書かれた記事なので、なおさら良い
ジャンプ後の命令を実行するというのは最初は正気じゃないように思えたが、数日経つと自然に感じるようになった。N64にも似たような問題があって、2つの乗算の間に入れる命令を探さなければならなかった
最初の乗算が0を掛けるなどして2サイクルで終わると、次の命令も乗算だった場合にCPUが停止していた
そのため例外が発生すると、カーネルの割り込みハンドラは次の命令がCOP2かどうかを確認し、二重に実行しないようプログラムカウンタに4を加えなければならなかった
またCOP2命令は分岐遅延スロットに入れられなかったが、おそらく似たような理由だったのだろう。ところが一部のゲーム、記憶ではTekken 3が実際にそうしていた。多くのエミュレータがこの部分で問題を抱えたり特別な処理を必要としたりしたので、こっそり仕込まれたエミュレーション対策だったのではないかとずっと気になっていた
このシリーズの記事はいつも素晴らしい
PS1のゲームは今の基準ではそれほどよく持ちこたえないが、PS2のゲームを1440p〜4Kにアップスケールするとほぼ完璧だと思う
ノスタルジーの影響も大きいだろうが、確かな魅力があるし、PS1の独特なハードウェア制約を知ってからは時間が経つほど好きになった。ソーシャルメディアのフィードを見ても「PS1グラフィック」はちょっとした復興期を迎えていて、その雰囲気を再現しようとする人が多い
ゲームプレイの面で見ると、このコンソールは商業的に発売されたゲームだけでも数千本に及ぶ巨大なライブラリを持ち、隠れた名作も多い。その一覧の中から自分の好みに合うゲームをひとつも見つけられないゲーマーがいるなら、むしろその方が驚きだと思う