SEGADRIVE A21どおすりゃいいの? | //www.旧型、PSP開発幼稚園.game.jp/(本館)

SEGADRIVE A21どおすりゃいいの?

SEGADRIVE A21どおすりゃいいの?

ついさっき、五分ほど前(多分15分くらい前、気分優先)に、ついに諦めて、「A21」からやり直そうと、

別館から「A21」をDL。ここ2~3日。クラスライブラリ破壊したり、戻したり。
そんな事ばかり繰り返してたので、何処が不要で、どこがゴミルーチンか、ハッキリしてる。

その為5分くらい手を入れて、ゴミルーチンをばっさり削除。コンパイルしなおしてPSPで実行。

やはり、重くなってしまう。っていうか重くなる。なんつーか。fpsの数字も悪くなるんだが、
ゲームの動作全体も、まったりと遅くなる。(OutRunでテスト)

今、5分程作業した内容しか、変更してないんだから、自信をもって言うが、「どおすりゃいいの?」 なんつーか、fpsメーター隠しても、体感できるレベルで重くなる。はっきりいってアセンブラリストが 見れるのならば、それ見てちと検討比較してみたい。CPPの内部以外は全く弄っとりゃせんから、 GCCにそおいう機能があるのならば、読むべきアセンブラリストはホンの少しの筈だ。意味なんて全然 解からなくても、読みゃ何とでもなる筈。
困つたな。(注:拗音を小さく書くのって強制じゃないんだって、なるべくそお書いた方が望ましいんだって。) (03/19、20:42)
■A21ってさ。別に速くなったからUPした訳ではないんよ。たまたま管理人がおなか減ったからUPしたの。 今なら上にも書いてあるでしょ? 「PSP SEGA DRIVE実験版 A21」UPしたけど、おなかすいたつ♪ ってさ。あくまでおなかのつごーでUPしたんだから、明らかにやりかけのソースな訳。だって、おなかすいたら、 UPするしかないじゃん。他に管理人にどおしろというの。 おなかすくんだもん。おなかすいたからUPしたんだもん。悪いことしてないし、悪いもん喰つた記憶はないもん。 でも、ここ2~3日。病気でへばってるから、やっぱ悪いもん喰ったかも。ケーキ以外で。
■さらに要らない部分を排除してみた。さすがにずっと弄ってると何処が要らないか直ぐ判る。 すこし、持ち直した。が、まだ元のA21に比べて重い。 ええとFSKIP2なのにfpsメーター値で(これは速度であってfpsとは関係がない) -1~-2グライ。FSKIP2なんだから、極端なことを言えば、最小速度単位で、-3~-6遅くなってると、 言い直してもいい。(-値が遅いとする)
PSPのアッセンブラ全く解からないが、「不要な部分の削除」しかしてないので。アセンブラコードが、 小さくなっても、大きくなる事はあまりないだろう。だから、相対インデックスのような分岐命令は届くと思われる。 だから、純粋にALIGNなんじゃないの?見えないものは解からないんだけど。 (ワカラン、21:36)
■そういや「C言語」って関数名は実は変数なんだよね。って事は、何もCPPに頼らなくても、C言語で、 関数のALIGN記述出来るのかな?。関数のALIGNあわせをGCCが受け付けてくれれば、問題は一気に解決 する可能性がある。 変数のALIGNを受け付けるんだから、工夫すれば、関数のALIGNも受け付けるんじゃないかな。GCCが、 嫌がったら困るけど、ちと試しに記述してみよー。まーどーせコンパイルエラーの落ちだろうが、もしかしたら もしかするかもしんないじゃん。やってみよ。 (やってみよ、21:45)
■駄目。どおがんばって記述してみてもALIGN受け付けてくんない。でもこれは理屈上おかしい話だ。 だって関数名==変数名なんだから。void型のポインタを用意して代入したら、理屈上意味がない。 実体にALIGNあわせてくれなくちゃ。実体にALIGN合わせるのは「-O3」が自動でやってくれるのかな。 それともやってくれないのかな。明らかに症状がALIGNっぽいけど、ALIGNと関係ないのかな。 詳しくないからワカンナイ。ああ、アセンブラなら物凄く簡単な事なのに。関数の直前に馬鹿みたいに毎回 ALIGN合わせ書くだけなのに。VisualC++なら、何にも言わなくてもちっとオプション弄るだけで、自動で やってくれるのに。ああ、PSPワカンナイ。 (ワカンナイ、21:55)
■今度はもちっと不要なルーチンを削除し、ついでに某所の「安全弁」も解除した。 「安全弁」を解除したから、ゲームによってはおかしくなる可能性がある。が、管理人の直感で、 「まず100%OK」じゃろ。 ちなみに「不要なルーチンを削除」する過程で、分岐ルーチンも減っている。つまりPSPのミスキャッシュ ペナルティーがどうのこうの(だって最悪70クロックとか言ってたジャン、2~3日前の日記)って話なら、 大幅に改善されて、然るべきだ。そこのルーチンはバリバリ使ってる場所で、不要なコードではあるけど、 バリバリ通って(実行して)いる部分。そこの分岐を削除したのだから、ええい要するにこう。
□初めの状態
if(式){//←この式が安全弁 使う }else{ ゴミ }
□さっきの状態
if(式){//←この式が安全弁 使う }
□今の状態
使う
注:現実的に考えてこの「式」が成立しない可能性は考えがたい。

■なんと、上記のチェックを外すと「不思議ちゃん1」を実行させると暴走する。 つまりエミュ自体が落ちる。PSPの電源ボタン長押しである。 ちなみに、 起動しない「スラップファイトMD」 起動しない「サンダーフォースⅣ」 では大丈夫。 ここは、実機では、多分「アドレスエラー」になると思う。「アドレスエラー」になると、 スーパーバイザモードとユーザーモードが入れ替わって特定ベクタに復帰するんじゃなかったっけ? うーん、よく覚えてないが、そんなよーな動作だったような。もしくはIRQが発生するのかな? (注:m68000の場合NMIは番号忘れたがとにかくIRQ) ちと調べて みないと解からんが、「不思議ちゃん1」は「アドレスエラー」を発生させる。プログラムなんじゃないかな? うーん、Z80からアクセスしてここにたどり着かなそうだし、m68000のbyte系の場合、特別にアドレスエラーに ならないとしても、奇数番地WORDアクセスだよ?。ワカラン。 ちょっと調べないと判らんが、IRQの場合、実機で割り込み線を配線してない可能性がある。その場合、 そもそもアドレスエラーの割り込みがかからない。だから変なプログラムでもアドレスエラーで、止まる 事はない。強制的に次の命令を実行するし、スタックも変化しない。もしかしたらこういう風になってる 可能性もある。ハードウェアーの設計なんて、考え方によって様々だから、何も優等生的な設計になってる 必要等、何処にもない。ちと調べてみよ。 (23:30)
■もう一回、安全弁を戻してみた。 やはり、「不思議ちゃん1」は暴走しない。 つまり、差し当たり、ここの安全弁は解除してはいけない。場当たり的対応だが、仕方がない。 この安全弁は具体的にVDPコマンドのWORDアクセス、READとWRITEの二ヶ所。 この際、「不思議ちゃん1」は、どっちでこけてるのか確認しといた方が良いだろう。所詮二ヶ所なんだし、 果たしてREADかWRITEか。 (23:41)
■管理人の予想に反してなんとWRITEだった。確かに良く考えりゃPSPが落ちるんだからWRITEの 可能性が高い。がついうっかり無視した。心理的な問題である。 ということは、 メガドラは、「アドレスエラー」になった場合にIRQが発生しない可能性が高い。つまり配線してない。 X68000というパソコンの場合は、その線は(たったの一本だ)配線してあるので、「アドレスエラー」が 発生した場合IRQがかかりIRQベクタに飛ぶだろう。だがメガドラがその部分を配線してない場合、 端からIRQなど発生しない。が「アドレスエラー」には違いないので、SSPはどおなるのだろう。 少なくともスーパーバイザモードとユーザーモードが逆に切り替わるんじゃないか? もし、めんどくさいからスーパーバイザで突っ走れ式のプログラムならその時点でスーパーバイザだった ものがユーザーに切り替わってしまうのではないか?よく判らん。要調査だな。不思議なネタは尽きないな。 (あと3分で明日) ああもうお昼(夜の0:00)だから寝よかな。
■何で重くなるの? 差し当たり、
static unsigned short vdp_readword(void) { unsigned short result=0; switch(rw_mode) { case 0x00: result=*((unsigned short*)&vram [vdp_address&0xffff]); break; case 0x20: result=*((unsigned short*)&cram [vdp_address&0x007f]); break; case 0x10: result=*((unsigned short*)&vsram[vdp_address&0x007f]); break; } result = (result << 8) | (result >> 8); vdp_address+=vdpreg15; return result; }

static unsigned short vdp_readword(void) { unsigned char* vvv=0; switch(rw_mode) { case 0x00: vvv=vram +(vdp_address&0xffff);break; case 0x10: vvv=vsram+(vdp_address&0x007f);break; case 0x20: vvv=cram +(vdp_address&0x007f);break; } vdp_address+=vdpreg15; return ((vvv[0]<<8)|vvv[1]); }
にしてみた。要は全く同じ事をしてる。 そこの横のリンクから、PSPでの速いコードって書いてあるやり方に。 変更してみただけだ。 だが、OutRunは露骨に重くなる。FSKIP2で(-1~-2fps)グライ。 何で?
ああ、やっぱ、「=0」が悪いんだろうな、「プログラマー養成ギブス(-Werr)」外そうかな。ここに来る度=0のコードが 入るの嫌だからstaticにしようか。でもその場合、「別のデメリットが発生する可能性」すなわち 「レジスタ割付」してくんないと嫌だな。どおしよ。 昔のC言語みたいに、registerって書いていいんかいな?staticと両方書いてもレジスタ割付に共存してくれるの かな?そんな予約語、廃止されてるんじゃなかったっけ?どおなんだろ。 (次の日00:34)
さしあたり、 static unsigned char* vvv ; で、良いらしい。WARNINGが出ないから、STATICでレジスタ割付してくれると信じよう。さしあたり 確認する方法もないし。で、OBJコードが0xCDB6Cから0xCDB8Cに増えた。 常識で考えれば、メモリ割付したから、OBJコードが増えたと考えがちだが、 ここはレジスタ割付したから、OBJコードが増えたんだろう。さしあたり、確認の方法もないし。 で、速度、実験してみよう。
なんつーか、さっきよりは速くなった。 今OutRunFSKIP2、22050のチェックは止めて、 FSKIP0、22050にチェックの方法を変更した。 現状FSKIP0、22050は、とてもゲームになるスピードではなく生理的に不快だが、いづれはたどり着かなければ ならない場所だろ?FSKIP0、22050の場合微妙に速いような? FSKIP2、22050の場合は速くなったり遅くなったり。 もう、FSKIP2のチェックは止めようか。FSKIP2を基準にしてる限り、現状を見誤るんじゃないか? とにかくstaticは(可能な場合は)レジスタ割付されるらしい事が判明したな。これは儲けものだな。 いろいろ、staticにして実験してみよう。特にメモリ周りのルーチンはちょっと変えるだけで速くなるかもしれん。 今日は不要なルーチン削除しかやってないのに、A21より遅いレベルにある。明らかに遅いんだケドもう戻すの やだよ。だって、使ってないの削除すると、遅くなるんだもん。ちょっと変えても遅くなるんだもん。何だか今日も 疲れたよ。もう寝るっていうか。ここの更新はこの辺にしとく(つもり)おやすみ。(01:12)