[戻る] [English]
NOT YAROZE
Playstation Programming without official tools

C/C++による非公式PlayStationプログラミング

変更点

はじめに

PlayStationの開発環境としては、ソニーコンピュータエンタテイメント(SCEI)の公式なものとして、プロ用のものと、ネットやろうぜというアマチュア用のものがあります。

ネットやろうぜは、最新のゲームマシンのソフトをアマチュアが開発できるという点では非常に魅力的で、出版社と組んでコンテストを開催したり、プレプレ(体験版CD)で作品を公開するなど一定の成果は残したものの、(開発環境としては安いものの)学生等が気軽に出すには高い費用、所定のサーバで会員間でしかソフトを公開できないといった閉鎖性、情報不足などにより、全体としては低調で、予定の2万人の会員を集めることなく終了しました。

しかしながら、世界は広いもので、こうした公式な開発環境に頼ることなく、独自に解析してPlayStationの技術情報を公開したり、ソフトを作っている人もいます。 NAPALMにいくつかのソフトや情報が集積されています。

ここでは、合法的に入手できる情報/開発環境でのPlayStationのプログラミングについて解説していきます。最終的にPS用のライブラリを構築し、C/C++によるフリーの開発環境を目指します。

開発環境を入手する

ハードウェア

第一に、開発用のパソコン(ISAスロットのあるPC-AT互換機)と、実行用のPlayStation本体が必要です。Free Wingのパラレル転送ケーブルと転送ソフトを自作又は購入すれば、ISAスロットのないノートパソコンや他のマシン(PC-98)でも可能かも入れません。

Pro Action Replay for PlayStation

Pro Action Replay for PlayStation(PS-PAR)は、英DATEL社のゲーム改造用ツールです。PlayStationの拡張端子に差すことで動作し、もともとはゲームにパッチを当てて改造し、体力が減らないようにしたり、アイテムを入手したりといったcheat(ずる)をするためのものです。

Pro Comms Link

Pro Comms Link(PC-LINK)は、同じくDATLEL社の、PS-PARとパソコン(PC-AT互換機)を繋いで通信できるようにするパソコン用ISAボードです。PC-98用の同様のものも存在するようです。

caetla

caetlaは、PS-PARの内蔵ソフトウェアを置換し、ユーザーの作成したプログラムをPC-LINKで転送して実行するなどの機能を追加し、PS-PARを開発環境に変身させるものです。k-comm.氏が作成され、Deaf Dumb & Blindで公開されています。機能や詳しい使用法はこちらを参照してください。

まず、PS-PARとPC-LINKを秋葉原の専門店やゲームラボの広告やWeb上で通販している輸入販売業者等から購入します。両方で1〜2万円くらいです。次に、PS-PARのフラッシュROMをcaetlaで置き換え、パソコン上のプログラムをPlayStationに転送して実行できる環境を整えます。

ソフトウェア

開発は基本的にDOSまたはWindows95のDOS窓のコマンドラインで行いますが、 コンパイラや転送ツールを再構築すれば、他のOS上でも可能です。 PlayStation development with BSDでは、BSD用のPAR+caetlaデバイスドライバ、gcc等のパッチ(いわゆるports)が公開されています。

GNU C/C++ Compiler

GNU C/C++ Compiler(gcc)は、多くのプラットフォームに対応したフリーのC/C++コンパイラです。PlayStationのCPUであるMIPS R3000にも対応しています。ソース配布されているので、開発を行うマシン(host)と、実行マシン(target)を指定してやればクロスコンパイラとして構築することができます。

GNU binutils

GNU binutilsは、同じく多くのプラットフォームに対応したアセンブラ(as)・リンカ(ld)・ライブラリアン(ar)等のパッケージです。アセンブラでの開発なら、こちらだけでかまいません。 一般的にバイナリオブジェクト形式にはa.out,coff,elfなどいくつかありますが、ネットやろうぜでは"ecoff"というのが使われています。また、最終的なCD-ROMのファイルでは、俗にPSX-EXEと呼ばれるPlayStation独自形式が使われています。caetlaは両方とも対応しています。ecoffからPSX-EXEの変換には、hitmenのeco2exeといったツールがあります。

GCCやbinutilsは、各地のftpサイトからソースを入手して自分で構築することもできますが、Win32/X68k用にコンパイル済みのものが非公式CO HOMEPAGEで公開されています。

ソフトに添付されているドキュメントは英文ですが、これらはもともとUnix上のソフトで、Linux,FreeBSD,NetBSD等のUnix系のOSのページでUnix関連の各種ドキュメントが日本語に翻訳されているので、これらに関するドキュメントもあります。また、日本語の書籍もいくつかあるようです。

最近のWindowsのビジュアル開発環境しか知らない方はとっつきにくいでしょうが、X68kやMS-DOS(DJGPP)でコマンドラインでの開発に慣れている方は、特に新しいことを覚える必要はありません。

GCCには多くのオプションがありますが、よく使うのは以下のオプションです。

-S
アセンブラコード(.s)を出力
-c
オブジェクト(.o)を出力
-O2
最適化を有効
-o <file>
出力ファイル名を指定
-D<macro>
-D<macro=def>
マクロを定義する
-l<xx>
libxx.aというライブラリをリンクする
-Xlinker <option>
リンカにオプションを渡す
リンカに複数のオプションを渡す場合は、-Xlinkerを複数回並べます。よく使うものは
-Xlinker -Ttext -Xlinker <hex address>
生成アドレスを指定する(CO gccのデフォルトは80100000)
-Xlinker -meco/-mpsx
ECOFF/PSX-EXE形式で生成する(CO gcc拡張:デフォルトはELF)

GNU Make

MAKEとは、一定の書式に従ったMakefileというファイルを記述することにより、複数のファイルのコンパイル等を自動化するものです。 長いコマンドラインオプションや複数のファイルのコンパイルが面倒な場合は、DOSのバッチファイルを使用することもできますが、MAKEを使用すると、もっと簡潔に記述でき、更に、ファイルの日付を調べて必要なものだけコンパイルするようにできます。

必須ではありませんが、便利なことと、公開されたソースにMakefileが添付されていることも多いので、入手しておくほうが良いでしょう。MicrosoftのNMAKEやwatcomのWMAKE等、既存のコンパイラに付属しているものもありますが、微妙に書式が違うので、GNU Makeを入手しておくのが無難です。

MAKEは処理系依存しないので、djgpp用mingw32用などのコンパイル済のものをそのまま利用できます。


これで、基本的なハードウェア環境とソフトウェア環境が揃いました。ネットやろうぜ、プロ用の開発環境とも、GCCをベースにしているようなので、ほぼ同じ環境が揃ったことになります。ネットやろうぜは最高115200bpsのシリアル転送なので、PC-LINKのパラレル転送の方がむしろ快適なくらいです。

ただ一つ足りないのはライブラリです。 GCCは、一般的なC標準関数については、対応するlibcというものがフリーで公開されていますが、パッドの入出力やポリゴンの描画といった、PlayStationに依存したライブラリはありません。 公式の開発環境ではPlayStationのハードウェアを制御するライブラリが付属していますが、一般にはそんなものは公開されていません。この部分は自作する必要があります。

そのためには、PlayStationのハードウェアがどうなっているかを独自に知る必要がありますが、現在では、世界中で解析がなされ、多くの情報が公開されているので、これらを利用することができます。

PlayStationの情報を入手する

CPUの情報

PlayStationに使われているCPUのMIPS R3000は、ワークステーション等で一般的なCPUなので、開発元のMIPSのサイト(今はSGIに買収されたのでSGIの中)で英文資料を入手できるほか、「MIPS RISCアーキテクチャ R2000/R3000」(共立出版 ISBN4-320-02598-9 C3041)通称「青本」(表紙が青い)という和訳書籍もあります。また、極楽プレイステーションでR3000の命令について解説されています。

PlayStation固有の情報

PlayStationのハードウェアの概要については、PlayStation FAQでも触れられていますが、SCEIからもネットやろうぜ用のものが一部公開されています。用語等についてはこちらを参照してください。

ネットやろうぜで入手できる情報は、以前は専用サーバで会員内にのみ公開されていたのですが、ネットやろうぜの終了と専用サーバの停止に伴い、一部は一般公開可になったらしく、ネットやろうぜライブラリのリファレンスや実行環境がWickedBeATで公開されています。 また、C Magazine(ソフトバンク)96年10月号でネットやろうぜとサンプルプログラムが紹介され、11月号から数ヶ月間プログラミングの連載がありました。これらは直接ネットやろうぜと同じ環境が手に入ったり、ハードウェア内部の機能がわかる訳ではありませんが、どんな機能があるかを知るための手がかりになります。

より詳しい情報に関しては、英語ですがBlackbagCREATURE - PSXbTmASTER's PSX-Development-Pageで解析された資料が公開されています。

前述のDeaf Dumb & BlindのPS開発ノート(仮)では、アセンブラでのプログラムの日本語の情報といくつかのソースが公開されています。 また、各種コントローラの信号やメモリカードのデータ形式がNiftyの藤田氏によって解析されています。

以下はBlackbagの資料の一部を翻訳・整形・補足したものです。

以下はその他の資料です。

PlayStationの制御

システムコールの利用

PlayStationにはBIOS-ROMが搭載されていて、ハードウェアを直接制御しなくてもBIOSのシステムコールでかなりのことができるようになっています。システムコールはかなりのものが解析されていて、呼び出しもCから簡単に行えるようになっています。

システムコール一覧

システムコールは、いくつか欠落/不明のものもありますが、Blackbagで公開されています。 こちらは翻訳・整形したものです。 また、一部はDeaf Dumb & Blindで日本語で解説されています。 解析資料ではCの関数ライクな名前が付けられていて、特にCの標準関数の名前のものは、一般的な使用法と同じと考えて間違いありません。その他の関数や構造体に関しては、前述のネットやろうぜライブラリリファレンスに、対応する関数の説明があるものもあります。

システムコールをCから利用する

システムコールでは、引数が必要な場合は常に$a0,1,2,3で渡され、5以上の引数は$sp+0x10で渡されます。そして$t1($9)にシステムコール番号を入れ、システムコールのアドレス(0xa0,0xb0,0xc0)をコールします。返り値がある場合は$v0($2)で返されます。

この引数の渡し方と返り値は、mips-gccの関数呼び出し規約と全く同じです。 したがって、引数($a0-3やスタックの状態)をそのままにして、$t1($9)を設定し、システムコールのアドレスにジャンプするラッパ関数を導入すれば、Cの関数として簡単に呼び出すことができます。

ラッパ関数の例:

プロトタイプ宣言:
int open(char *name,int mode);

実体:(アセンブラ)
open:
	li	$8,0xa0	#システムコールアドレス
	.set noreorder
	jr	$8
	li	$9,0	#システムコール番号
	.set reorder
ここでは、$8をジャンプのためのテンポラリレジスタに使用していますが、関数内で保存する必要のあるレジスタ以外であれば何でもかまいません。mipsの遅延分岐のためちょっとややこしいですが、平易に書けば
	li	$8,0xa0	#システムコールアドレス
	li	$9,0	#システムコール番号
	jr	$8
	#nop
となります。

open関数が呼ばれるとき、通常のCの関数のように$a0,$a1に引数が渡され、戻りアドレスを$raに入れてopenを呼び出します。 openでは$a0,$a1,$raはそのまま、$t1にシステムコール番号を入れてシステムコールにジャンプします。 システムコールでは、渡された$a0,$a1からシステムコールの処理を行い、$raのアドレス、すなわちopen関数が呼ばれた場所に戻ります。

この辺りは若干アセンブラの知識が必要ですが、アセンブラやGCCのインラインアセンブラで一度ラッパ関数を書いてしまえば、あとは楽です。

ハードウェアの制御

ハードウェアの制御は、0x1f801000-0x1f80????のメモリマップドI/Oを通じて行います。この資料はBlackbagに有ります。こちらが翻訳したものです。

GPU

GPU(グラフィックプロセッサユニット)は、PCの3Dアクセラレータボードに相当するもので、ポリゴン描画など、描画/表示全般を受け持つチップです。GPUを制御するには、フラット三角ポリゴン、グローテクスチャ四角ポリゴン等、個々のプリミティブ(基本図形)で特定の構造をもったコマンドパケットを送ります。これは、Direct3D Immidiate ModeのExecute Bufferと同様のものです。

GPUにコマンドを送るには、メモリマップドI/Oを使用してCPUで1ワード(32ビット)ずつ送る方法と、DMAを使用して複数のパケットのリンクリストを一気に送る方法の2つがあり、両方ともシステムコールにあります。 GPUのコマンドは前述のBlackbagで公開されています。こちらは翻訳したものです。

リンクリストは、通常のパケットの先頭に、パケットサイズと、次のパケットへのポインタが付いています。

  8bit   24bit
| size | next ptr |
| pkt[0]          |
| pkt[1]          |
| pkt[2]          |
   .               
   .               
| pkt[size-1]     |
下位24ビットは、次のパケットのアドレスの下位24ビットです。PlayStationはメモリが2Mしかないので、24ビット(16Mまで表現できる)で十分表現できます。 上位8ビットは、そのパケットのワード(32ビット)でのサイズです。0の場合は、パケットの実体がない空のパケットです。 リストの終了は、恐らく-1(0xffffffff)です。

GTE

GTE(ジオメトリエンジン)は、3Dの演算を受け持つ数値演算プロセッサに相当します。3D演算専用で、R3000の標準的な浮動小数点演算コプロセッサとは異なります。 なぜか解析情報の公開よりPSエミュレータの実装の方が進んでいたのですが、現在では CREATURE - PSXで公開されています。こちらが翻訳したものです。

SPU

SPU(サウンドプロセッサユニット)は、サウンドブラスタ等の音源ボードに相当します。動画等ではCD-ROM/XAを利用しているので、AD-PCMの波形方式にはXAを利用しているのではないかと推測できます。CD-ROM/XAは規格の一種なので、レッドだかイエローブックだかのCD-ROM規格書(高いらしい)を入手できるほか、 XA2WAVEのソース解析を楽しむページが参考になります。

SPUの解析が進み、既に音を出せるようになっているようです。 bITmASTER's PSX-Development-PageCREATURE - PSXに、SPUのレジスタ情報や波形コンバータ、サンプルコード等が公開されています。 こちらはCREATUREの資料の翻訳bITmASTERの資料の翻訳です。

MDEC

MDECは動画の再生(圧縮されたデータの展開)を行うもので、MPEG再生ボードに相当します(最近はCPUの性能が上がったのでソフトウェアの再生の方が一般的ですが)。caetlaは動画再生機能を既に実装しているので、制御方法は既に解析済みのようです。

CD-ROM

これもPSエミュレータで既に実装されているので、解析済みのようです。 低レベルの制御法もあるようですが、open("cdrom:filename;1",1);とすることで、open/_lseek/read/close/firstfile/nextfile等のファイル関係のシステムコールから使えます。

ただし、PlayStationのCD-ROMにはハードウェアとソフトウェアのプロテクトがかかっているので、普通のCD-ROMやCD-Rのデータを通常のPlayStationで読むことはできません。

メモリカード

メモリカードは、open("bu00:filename",1);(スロット2は"bu10:〜")とすることで、ファイル関係のシステムコールから使えますが、使う前に初期化が必要なようです。具体的な手順は、Deaf Dumb & Blindの「簡易メモリカード管理ツール」のアセンブラソースが参考になります。

コントローラ

標準コントローラからの入力はシステムコールにあります。初期化やパッド入力の具体的な方法はBlackbagで公開されています。 アナログコントローラやマウスは、こちらの解析が参考になります。システムコールでは3バイト目(0x5a)が読み捨てられて、以降がバッファに格納されるようです。震動パッドについては不明です。

ライブラリの作成

スタートアップコード

GCCでは_startから実行されるので、main()を呼ぶようにスタートアップコードを書く必要があります。また、main()の先頭で__mainが呼ばれます。 ここでは_startでbss領域の初期化とgpレジスタの設定を行い、__mainは何もしないようにします。

extern  long _fbss[];
extern	long _end[];
extern	long _gp[];
register long *gp asm("gp");

_start()
{
	long *adr;

	for(adr = _fbss;adr!=_end;*adr++=0);
	gp = _gp;
	main();
}

__main()
{
}

_start.c

_start.cをコンパイルして_start.oを作っておきます

  mipsgcc -O2 -c _start.c

システムコールライブラリ

前述のようにして、ラッパ関数のプロトタイプ宣言をするヘッダファイルと、実体となるオブジェクトファイルを用意します。C標準関数については、標準ヘッダファイルっぽくstring.hとかmemory.hとか分けた方が望ましいかもしれませんが、ここでは面倒なので全部syscall.hとします。「ライブラリ」と言うからには、不要なものをリンクしないように別々のオブジェクトをライブラリアンでまとめるのが望ましいのですが、ここでも面倒なので一つのオブジェクトファイルにします。

syscall.lzh

syscall.sをアセンブルしてsyscall.oを作っておきます

  mipsgcc -c syscall.s

C標準ライブラリ

C標準関数の大部分はシステムコールにありますが、足りないものはGNUのlibcから持ってくることができます。PlayStationには浮動小数点演算コプロセッサがありませんが、ソフトウェアの浮動小数点演算ライブラリもあります。当面、ゲームプログラミングですぐに必要なものでもないので、保留しておきます。

ハードウェアライブラリ

その他のライブラリ

行列演算関数

3Dのジオメトリ演算部分で必要となる行列/ベクトル演算関連です。 いずれにせよ似たような機能のものが必要になるので、 関数名や構造体、固定小数点形式などは、ネットやろうぜの仕様にあわせました。 本来はGTEを使うのでしょうが、ソフトウェアで実装しています。

matrix.lzh

高レベルライブラリ

続く・・・かもしれない

プログラミング

細かいライブラリの作成は後にして、システムコールだけを使って実際のプログラミングに入ります。

Hello world

とりあえずお約束のHello worldプログラムです。

#include	"syscall.h"

int main(int argc,char **argv)
{
	printf("Hello,world\n");
	return 0;
}
hello.cでセーブして
  mipsgcc -O2 -Xlinker -mpsx -o hello.psx hello.c syscall.o _start.o
でコンパイル、
  psexe hello.psx
で実行します。

ところで、PlayStationの標準入出力はどこでしょう? 実機には存在しませんが(nullデバイス?)、caetlaではホストマシンのコンソールになるように拡張されています。いわゆる「printfデバッグ」のためのものでしょう。

2Dポリゴンの表示

次にPlayStationらしい(?)プログラムとして、ポリゴンを表示してみます。 まだ3D演算部分がないので、とりあえずは2Dです。

GPUの初期化

画面サイズ、表示領域の設定、描画領域の設定など、一連の初期化が必要です。 これはGPUに一連のコマンドを送ることで行いますが、ROMのColorBarsの前半でそれらしいことをしているので、これを参考にします。

void Clear_(void)
{
}

void gpuInit(void)
{
	SendGPU(0);		/* GPUリセット ? */
	Clear_();
	SendGPU(0x03000000);	/* 表示マスク (表示有効) */
	Clear_();
	SendGPU(0x06c60260);	/* スクリーン水平開始/終了 (0/256) */
	Clear_();
	SendGPU(0x07040010);	/* スクリーン垂直開始/終了 (0/240) */
	Clear_();
	GPU_cw(0xe1000400);	/* 描画モード(表示領域に描画 ディザなし tpage0)*/
	Clear_();
	GPU_cw(0xe3000000);	/* 描画領域始点 (0,0) */
	Clear_();
	GPU_cw(0xe407ffff);	/* 描画領域終点 (1023,511) */
	Clear_();
	GPU_cw(0xe5000000);	/* 描画オフセット (0,0) */
	Clear_();
	SendGPU(0x08000000);	/* 表示モード 256x240/NTSC/ノンインターレース */
}
Clear_()はGPUフラッシュかキャッシュフラッシュか終了待ちか何かと思いますが、とりあえず無くても動作するようなので無視して空の関数にしておきます。

プリミティブの描画

プリミティブを描画するには、所定の構造のコマンドパケットを生成して、GPUに送ります。これもROMのRectangleでそれらしいことをしています。 そのままだとややこしいので構造体を使ってみます。

void test(void)
{
	struct {
		unsigned char r0,g0,b0,code;
		short	x0,y0;
		short	w,h;
	} boxf = {
		0,0,0,0x02,	//黒
		0,0,
		256,240
	};

	struct {
		unsigned char r0,g0,b0,code;
		short	x0,y0;
		short	x1,y1;
		short	x2,y2;
	} polyF3 = {
		255,0,0,0x20,	//赤
		50,0,
		0,100,
		100,100
	};

	struct {
		unsigned char r0,g0,b0,code;
		short	x0,y0;
		unsigned char r1,g1,b1,pad1;
		short	x1,y1;
		unsigned char r2,g2,b2,pad2;
		short	x2,y2;
	} polyG3 = {
		255,0,0,0x30,	//赤
		150,0,
		0,255,0,0,	//緑
		100,100,
		0,0,255,0,	//青
		200,100
	};

	GPU_cwb(&boxf,sizeof(boxf)/sizeof(long));	/* 背景塗りつぶし */
	GPU_cwb(&polyF3,sizeof(polyF3)/sizeof(long));	/* フラット三角形 */
	GPU_cwb(&polyG3,sizeof(polyG3)/sizeof(long));	/* グロー三角形 */
}

int main(int argc,char **argv)
{
	gpuInit();
	test();
	for(;;) ;
}
そのままmainから抜けるとcaetlaに戻った時に画面が消えるので、戻らないようにfor(;;);で無限ループにしています。

poly2d.c

ファイルの入出力

ファイルの入出力は、open/read/write/lseek/close等の、Cの低水準入出力関数に相当するシステムコールで統一的に扱うことができます。read/write/lseekは、デバイス固有のブロック単位で行う必要があります。CD-ROMは2048バイト、メモリカードは128バイトです。これらを使うに先立ち、ExitCriticalSection();で割り込みを許可する必要があるようです。

openに渡すファイル名は"デバイス名:ファイル名"の形で渡します。

デバイス名	デバイス
  cdrom:	CD-ROM
  bu00:		スロット1のメモリカード
  bu10:		スロット2のメモリカード
  pcdrv:	PCのハードディスク(caetla拡張)
CD-ROMのファイル名はISOのレベル1に従い、英大文字8.3形式の末尾に";1"が付きます。当然ながらCD-ROMにはwriteできません。

メモリカードを使うには、InitCARD(1);StartCARD();_bu_init();を最初に行う必要があるようです。また、メモリカードのファイル名は、各ソフトのセーブデータのファイル名が重ならないように、何らかの法則性を持った長いものが使われているようです。

ファイルの情報(ファイルサイズ等)やディレクトリを見るには、firstfile/nextfileのシステムコールを使います。これはDOSやWindowsの扱いと似ています。 lseekがブロック単位でしか行えないので、ファイル末尾にlseekしてその位置のファイルポインタをファイルサイズとする手法は使えません。

以下はDeaf Dumb & BlindのアセンブラのサンプルをCで書き直したもので、CD-ROMからpcdrvにファイルのコピーを行います。

sample.c

つづく

とりあえず何やってるかはFPCE for PSのソースでも見てください。

別の方法 : libpsの使用

通常、ネットやろうぜ環境でプログラムを作成すると、libpsを利用したものになります。 libpsはlibps.aとlibps.exeから成り、libps.aはプログラムにリンクされ、libps.exeはネットやろうぜのシステムCD-ROMから読み込まれます。

libps.exeとlibps.aの関係は、MS-Windowsのダイナミックリンクライブラリ(.DLL)と、DLLを利用するためのインポートライブラリの関係に似ています。プログラムにリンクされるlibps.aには、ライブラリ自体ではなく、libps.exe内にあるライブラリ本体へのジャンプテーブルのみが記録されています。

したがって、ネットやろうぜで作成したプログラムは、プログラムだけでなく、libps.exeがないと動作しません。 caetlaでは、libps.exeを事前に転送することで、ネットやろうぜのプログラムも実行可能です。

libps.exeは、いくつかのネットやろうぜ会員が自作プログラムとともに公開しています。 libps.aやヘッダファイルは、ネットやろうぜ会員以外は入手できませんが、 Mark Heath's Home Pageで ジャンプテーブルが公開されているので、同様のものを作成することは可能です。

libpsインポートライブラリとヘッダファイル

Win32用のgccであるcygwin32やmingw32では、Win32 DLLのための独自のインポートライブラリやヘッダファイルが使われているので、同様にlibps.exeのための独自のインポートライブラリやヘッダファイルを作ることは合法だと思いますが、私は法律家ではないので、あなたの判断で使用してください。

libps.lzh

testsuits

Hitmenでネットやろうぜ用のサンプルプログラム(YA.ZIP)が公開されているので、これをコンパイルしてみます。これにはlibps.exeも含まれています。 ネットやろうぜ用のソースは他にもPSX Developer's ConnectionPlaystation.Netなどにあります。

MakefileをCO's gcc用に書き換えます。

[OLD]

LINKER          = -Xlinker -Ttext -Xlinker 801b0000 -Xlinker
$(PROG): $(OBJS)
	$(CC) $(LINKER) -o $@ $?
[NEW]
CC = mipsgcc
LINKER          = -Xlinker -Ttext -Xlinker 801b0000 -Xlinker -meco
$(PROG): $(OBJS)
	$(CC) $(LINKER) -o $@ $? -lps

バッチファイル(A.BAT)はez-o-ray用なので、caetla用に書き換えます。

[OLD]

del main
del main.o
make
eco2exe -p main 
ez load libps.exe 8000f800
ez load picture.tim 80180000
ez run main
[NEW]
del main
del main.o
make
rem eco2exe -p main 
psexe -X libps.exe
psexe picture.tim -d80180000
psexe main
これでコンパイルと実行できるはずです。

CD-Rの作成

ハードウェアプロテクト

PlayStationのCDにはプロテクトがかけられており、CD-Rで焼いたソフトはそのままでは動作しません。CD-Rソフトを実行するには、特殊な環境が必要です。

CD交換方式

本物のCDで起動してプロテクトチェックをパスした後、CD-Rに入れ替えます。 通常は蓋を開けるとPlayStationのメニューになってしまうので、奥にあるスイッチを何らかの方法で押さえておく必要があります。 タイミングが難しいのですが、PAR類似品の中には適切なタイミングで止まる機能のあるものもあるようです。

MODチップ

PlayStation本体を改造して特殊なICチップを取りつけ、プロテクトチェックをハードウェア的にパスします。このチップはPAR同様に秋葉原やwebの通販で販売されているようです。web上でPIC(プログラム可能IC)上のソースが公開されているので、PICライタを持っていれば自作することもできます。

ソフトウェアプロテクト(エリアプロテクト)

これはCDに書き込まれているエリアコードをチェックして、海外のソフトが日本のPlayStationで、日本のソフトが海外のPlayStationで動作しないようにするものです。

海外版のソフトを一度イメージにして、日本のエリアコードに差し替え、CD-Rで焼くことで、海外版のソフトをプレイしている人もいるようです。

自作CD-Rでは当然このエリアコードは書き込まれていませんが、CD-Rイメージを作成後、エリアコードの部分を本物のCDから持ってくることでパスできます。

PSX-EXEの制限

実行ファイルはCDのクラスタ単位(2048の倍数)である必要がありますが、co版gccではこれを行いません。したがって適切にパディングして長さを調節して、あわせてヘッダ部も書き換える必要があります。ファイルの長さを切り上げ、新しい長さ-2048(ヘッダ長)を先頭の28バイト目から4バイトに書き込みます。これを行うツールがAndrew's Stuffにあります。

SYSTEM.CNF

dosのautoexec.batやconfig.sysにあたる、SYSTEM.CNFというファイルを作ります。
BOOT = cdrom:\POLY2D.PSX;1
TCB = 4
EVENT = 10
STACK = 801FFFF0
BOOT = は、起動するファイル名です。
STACK = は、恐らく初期スタックポインタの位置でしょう。
TCB,EVENTは詳細不明ですが、一般のソフトと同じ値にしておけばとりあえず問題無いでしょう。

CD-Rの作成

まず、CD-ROM XA mode 2、ISO Level1のファイル名でISOイメージファイルを作ります。 次に、先頭の16セクタ(37632byte)にあるエリアコードを本物のCD-ROMから抜き出し、作成したISOイメージに上書きします。 最後に、ISOイメージをCD-Rに焼いて完成です。

謝辞

見ればわかるように、あちこちに散在する資料をまとめただけなので、彼らなくしては何もできませんでした。特に 各氏/社に多謝。(敬称略)

参考文献・関連リンク

文中のそこらじゅうでリンクしているので、後でまとめます。 リンクの一部はこちら

[戻る]