2000-02-15

どれが最新版かわけがわからない状態なので、
DOS 用のプログラムの最新版(修正版 Ver0.32)
CDROM イメージの最新版(Ver0.30)
です。

連休中にバグを直そうと思っていたんですが、惨敗。
HD(Ver0.30 に付いてる16進ダンプと逆アセのプログラムです)で RETURN を押すとハングってしまいます。caetla でプログラム転送して試すと再現せず、CDに焼くと発病します。 801f0000 から、という狭いところに転送してるので、 最初スタックが溢れてるのかと思ったがそうでもない様子。よくわからんが caetla なしだと割り込みがないぶん速くなって DMA がらみでコケてるのかなーと漠然と考え、じゃあ真面目に割り込みと DMA に立ち向かうかと思ったところまではなかなか良い志しだったんですが、 ついでに CDROM の割り込みも試そうって思って書いてみたら大ハマリ。 ふてくされてポポロクロイスUを始める始末。 おかげでなんの成果も得ることが出来ませんでした。(泣
あ、現象は割り込みがかかったりかからなかったり、しかも不定期。まともとは思えません。 多分しょーもないバグなんでしょうけど、 同じような現象を体験済みのひとがありましたら助言よろしくお願いします。
 このページは言い訳のための日記になってしまいそです。 ほんとにそのうちHPをきれいに整理しますんで、しばらくおまちくださいませ。
 THUMP!さんからリンクのお許しをいただきました。ここです。PAR3 の通信プロトコルについて記述があります。 実行時改造コードの転送命令なんかもありますのでフリーソフトのネタに最適です。
 Kamilion さんが私のインチキ英語を Native な英語に翻訳(笑)してくれました。 ここです。
Herben さんが mfc0 $12 のことを教えてくれました。 bit0 はやっぱり割り込みを許可・不許可のビットだそうで、Doomed の system.txt に書いてあるそうです。うーむこのテキスト持ってたのに見逃してました。
 彼はリバースエンジニア専用ROMの開発計画進行中だそうです。 さそってくれたんですけど私はそんなに知らないんでそんな「だいそれた」ことはよーやりません。 実力がついて、なんかの間違いで自信がみなぎってきたらそのときはよろしくお願いします、て感じです。あと PS2 に穴を開ける計画が挫折したらやってみようか、 とか都合のいいことを考えたりしてます。
 そうそう、PS2。やっぱり PSDIS 相当のものが欲しいところですねー。今のうちに Windows でプロトタイプを書いておけばいいんだろうなーと思いつつ、 足取りは重いっす。そもそも WIndows でプログラムってかれこれ1年ぐらいやってないし、個人的には DOS 用(しかも HP200LX で動くような...)のほうが欲しかったり... ライブラリを整備して両方で動くモノを作るとかいうのが最高かなあなどと思いつつも C++ は使いたいし、結局手付かずって結末のような気がします。

2000-02-04

見てる人がいるかもしれんので本日の成果。 1f060030 に 3 で bank0, 1で bank1 などと申しておりましたが厳密には間違いでした。 起動時の状態は3で、初期処理の後に1にするんですが、本当の意味は bit1 に 1 を入れると起動時の ROM(1f000000-1f04ffff)、 0 だと別の ROM になります。 bit0 に 1 をいれると通常時の RAM(1f040000-1f05ffff)、0 をいれると別の RAM になります。なんに使ってるかは不明ですが、まだ一度も動かしたことがない V-Mem あたりに使ってるのかもしれません。RAM と言ってるのは sb とかで直接書き込めるからですが、電源を切っても前の状態を結構覚えてる感じなんで Flash なんとかかなーと思います。
なんだかまた仕事が忙しくなってきた。 でも思いの他反響があるのでやめる訳にもいかず、どーしよーって悩む今日この頃です。

2000-01-09
2000-01-19
2000-01-26
2000-01-31

!!!そのうちHPをきれいに整理しますとも!!!



PAR3.2 と 3.1 以前(多分。 3.0 は持ってないので。)では通信方法がちょこっとだけ ちがってました。

どう違うかというと、まあとりあえず THUMP! さんの解析ページを見てから読んでほしい んですが、(URL は書いていいか分からないので探してください)
2000-02-15 リンクのお許しをいただきました。 ここです。
ゲーム中に PC が 3 を送信すると、3.1 までは 0 を返してくれました。 3.2 では返しません。 3を送信する、という行為は「これから通信するからよろしくね」っていうサインです。
その後は 3.1,3.2 共通で、

PC       PS
'G' >>>>
    <<<< 'g'
'T' >>>>
    <<<< 't'
cmd >>>>
というシーケンスになります。通信は 4bit ずつ行われるので 'g' は 6 を送って 7 を 送る、ということになります。 3.1 では
3  >>>>
   <<<<  0
4  >>>>	        'G' の上位4ビット
   <<<<  6      'g' の上位4ビット
7  >>>>         'G' の下位4ビット
   <<<<  7      'g' の下位4ビット
cmd>>>>
   <<<<  0
cmd>>>>
   <<<<  0
てな感じだったのですが、3.2 では
3  >>>>         これが来てるのを確認しつつスルーして、
   <<<<  6      'g' の上位4ビット
dummy  >>>>	(多分 0 とか)
   <<<<  7      'g' の下位4ビット
ここで 30 などというありえないコマンド番号を貰った PS 側は再び 'g' を送出 するところにジャンプします。

そういうわけですので、今までの ar3read ではエラーが出たり出なかったり不安定 だったというわけです。

さらに!!!

3.2 ではアドレスのチェックがいいかげんになっていました。

1f000000 から取り込もうとすると強制的に 80010000 からのメモリを送信しますが これが 9f000000 とか bf000000 を指定すると、しっかり ROM 領域を返して くれます(笑)。
同様に 80000000 からも a0000000 を指定すればOKです。 00000000 を指定するのは特別な意味があるので不可です。 そーゆーわけでそのうちPC側のプログラムを更新しますんでしばらくお待ち下さい。
表のページに PAR3 Reflash Tool を公開。ダウンロード
PAR3 つぶれた人とつぶれてもいい人は試してみてください。

この話は Ver0.20 のお話です。0.30 ではこれはいらないはず。 はあ、caelta に書き換えちゃった人がでてしまいました。全然想定してなかったです。 甘かったなあ、と反省してますが、 このツールはROMを書き換えたあとのお行儀が悪くて、 バンクを裏にしたまま終わってしまいます。 PAR3系のROMだったら起動時にバンクを元に戻すのですが、 それ以外のだとどうやら裏のROMのままみたいです。 (しばらく置いておくと戻ったりするかもしれませんけど、知らない。) 一応回避策として超ちっちゃなプログラム出しておきます。 手動でバンク切り替えを行えます。
それから caetla に書き換えても I/O 各種が違うので動作しない機能が多々でますので、 興味本位でやるのはお勧めしません。 ただし壊す覚悟がある人はどんどんいろんな事を試してください。
それに私のプログラムは自分でいうのもナンですが、 初心者レベルなんでフックしまくるROMから起動するとなにが起こるかわかりません!


PAR3 の解析ですが、気が向いたらやっていこうかと思います。 ある程度の成果が出たら別のページに書いたのもあわせて、 まとめたいと思います。

ROM 書き込み手順

実行時に吸い出したイメージの 1f040800 (ここは RAM です)以降に EEPROM 書き出しのプログラムを発見しました。 関数は順番に、
  1. 1f040830 void Unprotect(void)
  2. 1f04088c void Protect(void)
  3. 1f0408e8 void ToggleBit(sectorAddress)
  4. 1f040938 void WriteData(destAddress, srcAddress, size)
  5. 1f040a44 int VerifyData(destAddress, srcAddress, size)
  6. 1f040aec void Write_Verify_RebootAnyway(destAddress, srcAddress, size)
(勝手に命名)となっています。 一番親玉の Write_Verify_RebootAnyway() から書きます。 アドレスの下位 8 bit が 00 から ff の間を便宜上セクタと呼びます。
void Write_Verify_RebootAnyway(destAddress, srcAddress, size)
{
	WriteData() をコール
	VerifyData() をコール
	戻り値に関らずリブート、をいをい。
}
void WriteData(destAddress, srcAddress, size)
{
	割り込みを禁止。
	ToggleBit() をコールしビジーでないことを確認。
	Unprotect() をコールし、書き込めるようにする。

	セクタ先頭バイトに $20(Erace #1)を書く。
	セクタ先頭バイトに $d0(Erace #2)を書く。
	ToggleBit() コール

	セクタ数だけループ {
		for (i = 0 ; i < 256 ; i ++) {
			セクタ先頭バイトに $10(Byte Program)を書く。
			セクタ先頭バイトに srcAddress から順番に書く。
			2000-01-19 追記:これはウソ!先頭じゃなくて、
			そのまま書き込むところに書いてます。
			ToggleBit();
		}
	}
	Protect() をコール、書き込めないようにする。
	割り込みを許可。
}
void ToggleBit(sectorAddress)
{
	セクタ先頭バイトを読む。
	もう一度読む。
	一致するまでループ。
}
void Protect(void)
{
	lbu (1f001823)
	lbu (1f001820)
	lbu (1f001822)
	lbu (1f000418)
	lbu (1f00041b)
	lbu (1f000419)
	lbu (1f000410)
}

void Unprotect(void)
{
	lbu (1f001823)
	lbu (1f001820)
	lbu (1f001822)
	lbu (1f000418)
	lbu (1f00041b)
	lbu (1f000419)
	lbu (1f00041a)
}

int VerifyData(destAddress, srcAddress, size)
{
	src と dest を size 分比べる。
	同じなら 0、違ったら -1 を返す。
}

不明なこと

あっちのページにも少しかいていますが I/O の 1f060038 の bit0,bit1 がわけわかりません。 同様に 1f060030 の bit2,bit3 もよくわかりません。 これさえ分かれば安心して flasher を書けるんだけど... いや安心は出来ないけど、でもうまくいかなかったらもう一個買えばすむことだし。

参考文献:

SST 4 Megabit(512K x 8) SuperFlash EEPROM
SST28SF040/SST28LF040/SST28VF040
(www.SuperFlash.com or www.ssti.com だそうです。)
hanimar@reocities.com