□「なんとかHOME終了可能になった。」までワープ。
□「FILERまで起動」までワープ。
□「起動に失敗しました。(800200D9)」までワープ。
3/06 PG #2 馬HOMEダメ2006-03-06 10:31:33
#02 HOME終了の謎
とにかく、お馬ちゃん。立ち上がらない。どんな馬でも生まれたら立ち上がるのが普通だぞ。いや、まだ
生まれる前か。
■generatorは68000のobjが1089kb(現在値)ある。
これは、「gen68k.c」による自動生成ソースだから、弄りたくなかったが、ちと弄ってみた。
だが、少し弄った位じゃ全然小さくならない。うまく動かないと困るし。
いっその事。CPUいれかえちゃえって案もある。
■OBJが届かないと嫌なので、
$(OBJ)/startup.o \ ←ここがstartup.Sだよ。
$(OBJ)/state.o \
$(OBJ)/uiplot.o \
$(OBJ)/uip-psp.o \
$(OBJ)/ui-psp.o $(OBJ)/pg.o \
$(OBJ)/generator.o \ ←ここにxmainがある。
$(OBJ)/gensoundp-psp.o \
$(OBJ)/_pspstd.o \
$(OBJ)/gensound.o \
$(OBJ)/psg/psg.o $(OBJ)/ym2612/ym2612.o \
$(OBJ)/render.o \
$(OBJ)/vdp.o $(OBJ)/event.o \
$(OBJ)/memz80.o \
$(OBJ)/mem68k.o \
$(OBJ)/reg68k.o $(OBJ)/setjmp.o \
$(OBJ)/cpu68k.o \
$(OBJ)/cpuz80.o \
$(OBJ)/cmz80/z80.o \ ←ここまでのOBJ全部足しても700なんぼしかない。
$(OBJ)/cpu68k/cpu68k_0f.o \ ←さっきの1089kb(現在値)だよ。
という順序にした。cpu68k_0fというのは68000全部纏めてある。
「pg.c」の中身も見直して、
void pgWaitV()
{
sceDisplayWaitVblankStart();
}
void pgScreenFrame(long mode,long frame)
{
pg_screenmode=mode;
frame=(frame?1:0);
pg_showframe=frame;
if (mode==0) {
//screen off
pg_drawframe=frame;
sceDisplaySetFrameBuf(0,0,0,1);
} else if (mode==1) {
//show/draw same
pg_drawframe=frame;
sceDisplaySetFrameBuf(pg_vramtop+(pg_showframe?FRAMESIZE:0),LINESIZE,PIXELSIZE,1);
} else if (mode==2) {
//show/draw different
pg_drawframe=(frame?0:1);
sceDisplaySetFrameBuf(pg_vramtop+(pg_showframe?FRAMESIZE:0),LINESIZE,PIXELSIZE,1);
}
}
void pgInit()
{
sceDisplaySetMode(0,SCREEN_WIDTH,SCREEN_HEIGHT);
pgScreenFrame(0,0);
}
標準と思われるこんだけ。しか使ってない。
「startup.S」も実際動いてる小さなプログラムの奴をコピーして使用。
■それでも、立ち上がらない。
管理人の望みは、「単なるHOME終了」だけだよ。
該当部分のソースは全部小さなプログラムから抜いてきた。(もちろんHOME終了のレジスト/コールバック部分もチェックした)
それでも、小さなプログラムはちゃんとHOME終了できて、
generatorのOBJリンクさせたでかいプログラムは、起動しないし、目がいっちゃってて、あちらの世界へワープ
してるし。ううう、お馬ちゃんヤクは駄目よ。今からそんな事では、りっぱな競走馬に育たんぞ。
...HOME終了ぐらいさせてくれ。
管理人が始めてHelloWorldにHOME終了つけた時、RIN132カンニングしたから、実行まで5分も
かからなかったよ。今回はもう1日たってるよ。5分の何倍か知らんが、割り切れないよ。
(注:数学的に割り切れても、管理人の気分が割り切れない為。このページは数学より気分が優先。念の為。)
(03/06、11:01)
■もしかして「68000全部纏めてある。」って意味ワカンナイかもしんないから追記。要するにこう。
/************************************************************************/
/* Generator - Sega Genesis emulation - (c) James Ponder 1997-2001 */
/************************************************************************/
/* */
/* cpu68k_0f.c */
/* */
/************************************************************************/
#include "cpu68k-inline.h"
#include "cpu68k-a.c"
#include "cpu68k-f.c"
#include "cpu68k-e.c"
#include "cpu68k-d.c"
#include "cpu68k-c.c"
#include "cpu68k-b.c"
#include "cpu68k-9.c"
#include "cpu68k-8.c"
#include "cpu68k-7.c"
#include "cpu68k-6.c"
#include "cpu68k-5.c"
#include "cpu68k-4.c"
#include "cpu68k-3.c"
#include "cpu68k-2.c"
#include "cpu68k-1.c"
#include "cpu68k-0.c"
こうやって、C言語のソースでC言語のソースをインクルードする。このやり方はOBJをひとつに纏めたい、
あらゆる場合に役に立つ。
例えば"cpu68k-1.c"で、勝手にstaticで書いといて、"cpu68k-0.c"でそれをstaticの様に使用してもなんの問題もない。
個別のファイルを見れば明らかに「static」がおかしいが、なにも拡張子が「c」だからって、個別にコンパイルして
リンクするのは強制ではない。(その為にmakefileを書く)
正攻法のやり方ではなくても、「予めその様に設計すれば」何の問題もない。但しその場合は、自動的に
「Makefileもソースリストの一部」だ。という事を、お忘れなく。「Makefile」がなくなっちゃうと、本当に訳がワカンナク
なると思うよ。
(どおしても、気持ち悪ければ拡張子を「h」にするやりかたもあるけど、手間ばかり増えてメリットはないし、
いづれにしても後でMakefileが無ければワカンナクなるのは全く一緒なので、お勧めしない。
現在世界的にも、無理に拡張子を「h」にするのは「知ってはいるが誰も使わない方法」だ。メリットは全くない。
ちなみに世界的に、「やっぱ2タブはうざいから4タブにしよう」って事らしい。やっぱ「4タブ」だよな。
タブの歴史:「8タブ」→ここでは語り尽くせない→所により「2タブ」発生→やっぱ「4タブ!」)
「とにかくここはひとつのOBJにくっついてて欲しい」という場合に、管理人がよく使う方法だ。だって早いもん。
こうすると、「今までstaticには出来なかった部分」が「static」に出来て、速度面でお徳になる場合がある。
■そうそうせっかくだから、includeの使い方。基本的な事だけど、
#include "cpu68k-0.c"
と
#include <cpu68k-0.c>
は意味が違う。(探し方が違う)
#include "cpu68k-0.c"は、自分の所とか-Iで指定した場所とかを探す。
#include <cpu68k-0.c>は、システムの標準的なヘッダファイルが入ってる所を探す。
これは厳密には「C言語の使い方」ではなくて、「プリプロセッサの使い方」だな。でも100%標準だけど。
頭が#で始まるのは、「プリプロセッサ」がやる仕事。
#if 0 // 絶対に成立しない==コメント
昔のプログラム
#else // さもなければ==つまり使う
手直しした奴
#endif // (絶対に成立しない)のおしまい
とかは良く使うでしょ?あとは、
#define XTAL68K (3579545*7.5) // 「XTAL68K」を「(3579545*7.5)」で定義
とかさ。
#undef XTAL68K // 前の定義を消す
#ifndef XTAL68K // 定義されてなかったら
#define XTAL68K (3579545*7.5) // 定義
#endif // (定義されてなかったら)のおしまい
とか。
別にC言語講座にしたい訳じゃないんだけど、調べるのめんどいし、調べても意味が良くワカンナカッタり
するし。(基本的な所って、意外とうっかり誤解しやすいんだよね。わかっちまえは簡単だよ。つーか世の中に、
判ってもなお、「簡単でない」ものなど存在しない。わかったら判ったで、「めんどくせぇ」ってものは存在するけどな)
(13:00)
■C言語講座っぽいネタが書いてあるからついでにもう一つ。
みんな、判ってないな。と思うのは、「プロトタイプ宣言」だな。
「プロトタイプ宣言」ってのは、「必要な道具」で「ありがたい」ものなんだぞ。ただし上手く使えばだが。
「酒」は飲んでも飲まれるな。
「プロトタイプ宣言」は使っても使われるな。
みーんな「プロトタイプ宣言」に使われてるじゃん。
「プロトタイプ宣言」は使うものであって、使われるものではないんよ。
「C++言語」はともかく、「C言語」は「プロトタイプ宣言は少ない方が良い」
これは時代錯誤な考え方かと「非常に誤解されやすい所」ANSI-Cは、プロトタイプを絶対に書かなければ
いけないコーディングなど、勧めてはいないし。コンパイラも「無闇やたらとプロトタイプがあるかどうか判断」
してる訳ではない。きちんとした法則がある。
初心者だと、「えーだって、プロトタイプ宣言がないとWARNINGが出たり、コンパイルして実行させたら、
異常動作してプロトタイプ宣言追加したら直ったよぉ。プロトタイプ宣言ってやっぱいるんだよ」
とか反論するだろな。それは、「WARNING」の内容をきちんと理解してないし、プロトタイプ宣言を追加して
直るからといってそれが最もいい形という訳ではない。
現在のGCCではプロトタイプがない関数が出てくると戻り値intにしてWARNINGだしてテキトーに処理する
みたい。(-Werrの場合は別)
例えば次のプログラム。
void nago_nago(void){
static nya=1;
}
int xmain(void){
nago_nago();
return 123;
}
これはOK.
void nago_nago(void); // プロトタイプ宣言。
int xmain(void){
nago_nago();
return 123;
}
void nago_nago(void){
static nya=1;
}
これもOK.
そんでそれ以外の形はやめといた方が良い。プロトタイプ宣言は普通ヘッダに入ってる。その場合。
extern void nago_nago(void); // プロトタイプ宣言。
すぐ上のタイプも別にこれと同じでよい。
上の2つのサンプル。違いは順序のみ。「プロトタイプ宣言」の少ないプログラムの方が、「考え方が整理」されている。
「プロトタイプ宣言」は道具だから、「どうしてもプロトタイプ宣言がなければ記述出来ないプログラム」と言うものが、存在する。
「再帰(複数の関数を互いにコールする複雑なタイプのみ)」「配列内のラベル」「ジャンプテーブル」等。
これらは、「絶対にプロトタイプ宣言が必須」である。
つまり、ナンデモカンデモ「プロトタイプ宣言」を書くと、ダミーが多くて「本物」を探すのが大変だし、
不必要にソースリストが長くなって(だから普通「h」で誤魔化す)無駄なもんが多くなると、
必要なもん探すのが大変だろ。
って話。何の事かワカンナクていいよ。どおせ(説明不足で)誰も判らん。
酒は飲んでも飲まれるな!
■じゃあ試しに上の2つのプログラムのnago_nago関数をstaticに変更してみよう。何ヶ所直すかな?
直すヶ所が多い程。時間がかかるし、エンバグも増えるし。「h」にヘッダをまとめてあったら、該当ヶ所
探すの簡単ではないんよ。大抵その場合を考えて、「同じ名前.h」にしてあるけど、要らないなら要らないで、
「不必要な「h」ファイルが増えなくて済むし、長さも短くてすむ(見る場所が少なくて済む)」
■日本ってさあ、「努力したほうがえらい」みたいな訳わかんない社会だけどさあ。その「努力」が必要なら、
「した方がえらい」けど、不必要なら「しないほうがえらい」にきまってんじゃん。どおしてもっと基本的な、
「必要」「不必要」で物事を考えられないのかな。
必要ない「努力」をするのはピー。でも、必要ない「努力」を沢山する奴の方が、仕事してるみたいに見えて
まわりの受けは良い。管理人みたいに五分やって、一日分の作業済ませたからいいやって。他は遊んでる
タイプは受けが最悪。それがガンガッテ一週間分を実質済ませたとしても、全く同じ。そいつの仕事も全部
かけもって、やってやっても、まったく同じ。(っていうかそおいう事すると、却って恨まれる)
人間見えないものは判らない。
注意しよう。
(03/06、14:31)
(2006-04/11、追記)
■馬CPUは融合されてるので、入れ替えは結構難しい事に気がついた。(6ボタンパッドとかCPUのクロック直接見てるし)
■PGENEのMPUに融合した方が良いと思われる部分は融合した。(OPJサイズで200Kぐらい。)
■CCのOPTを見直す。
#CC_OPT = -O3 -mgp32 -mlong32 -msingle-float -mabi=eabi -c
を
CC_OPT = -O3 -fomit-frame-pointer -fno-exceptions -mgp32 -mlong32 -mabi=eabi -c
(DGENと同じ)
にしたら、EBOOT.PBPが1774kBytesから1164kBytesに減った!嬉しい。
但し多分mapは吐かなくなると思う。逆に言えば、mapを吐かせて効率を検討したい場合は、
わざとOPTを変えてコンパイルするのも、あり。という事だ。実験と割り切るなら、それなりに有用な技術だな。
(2006-04/11、追記)
■■なんとかHOME終了可能になった。原因は、アセンブラに渡すオプション。
でも、現在何故か「簡単な描画プログラム」を受け付けない。なんでたろ。
#駄目
$(OBJ)/%.o : src/%.S
$(CC) -mgp32 -c -xassembler -O -o $@ $<
#OK!
DEFINES =
AS_OPT = -mgp32 -mlong32 -msingle-float -mabi=eabi
$(OBJ)/%.o : src/%.S
$(CC) $(DEFINES) $(AS_OPT) -c $< -o $@
■■■フフフフフ。つついに!
(背景はグラデで、赤い線はグラデです。右が暗い。この色実は元のソースがバグって出た色(青と緑が出ない)と判明)
ってゆーか。まだ立ち上がっただけで、どおなるやら。
第3のメガドラえみゅは降臨するのか?
(2006-06/20、20:33)
■■68kに割り当てるメモリ。オリジナルは「必要になったらmalloc」でぶんどってるケド(つまりrealloc)
そんなもんはナイから、始めから配列で使う分確保してる。
で、1っヶ所確保量がヨクワカンナイ所があった。
さしあたりコンパイル優先なんで99にしといた。
で、99は少なすぎる。(と思う)
で、ヨクワカンナイから9999にしてみた。
で、ダメ。んなら、69999にしてみた。
そしたら長がーながメモカ読んで、
「起動に失敗しました。(800200D9)」
が出た。
これは「初めて見るぞ」
「起動に失敗しました。(80020001)」
とは違うぞ。ちゅー事で、「D9」は「メインメモリ容量不足」だと思うです。タブン。
(2006-06/21、10:55)