スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


続々・X68000 エミュレータ xkeropiのMPUコアをC言語化する

そんなわけで、デバッガにかけてみた。

xkeropi: x68k/mem_wrap.c:576: BusError: Assertion `0' failed.

Program received signal SIGABRT, Aborted.
0xb7fdd424 in __kernel_vsyscall ()
(gdb) where
#0 0xb7fdd424 in __kernel_vsyscall ()
#1 0xb74bfb1f in raise () from /lib/i386-linux-gnu/libc.so.6
#2 0xb74c30b3 in abort () from /lib/i386-linux-gnu/libc.so.6
#3 0xb74b8877 in ?? () from /lib/i386-linux-gnu/libc.so.6
#4 0xb74b8927 in __assert_fail () from /lib/i386-linux-gnu/libc.so.6
#5 0x08053537 in BusError (adr=adr@entry=12582909, unknown=unknown@entry=0)
at x68k/mem_wrap.c:576
#6 0x080536bb in cpu_readmem24_word (addr=12582909) at x68k/mem_wrap.c:369
#7 0x080909fd in C68k_Exec (CPU=0x88b0dc0 , cycles=200)
at m68000/c68k_op.c:649
#8 0x080a1e5d in WinX68k_Exec () at x11/winx68k.cpp:410
#9 0x080a2352 in idle_process_splash (p=)
at x11/winx68k.cpp:559
#10 idle_process_splash (p=0x0) at x11/winx68k.cpp:552
#11 0xb786bf10 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#12 0xb786f3b3 in g_main_context_dispatch ()
from /lib/i386-linux-gnu/libglib-2.0.so.0
#13 0xb786f750 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#14 0xb786fc2b in g_main_loop_run () from /lib/i386-linux-gnu/libglib-2.0.so.0
#15 0xb7b5c710 in gtk_main () from /usr/lib/i386-linux-gnu/libgtk-x11-2.0.so.0
#16 0x0804bb15 in main (argc=1, argv=0xbffff2e4) at x11/winx68k.cpp:739
(gdb)


cpu_readmem24_word()というメモリ読み込み関数で、引数addr=12582909なので、奇数番地またぎのワードアクセスを実行しようとして、assert()で落としているようですね。
なんで奇数アドレスでワードアクセスしているの?ということで実行トレースをとってみた。

<43F9> (00FF023C ->) 00FF023E : lea     $ff0264.l, A1
D0:FFFFFFFF D1:00008000 D2:00000000 D3:00000400 D4:00000000 D5:00000000 D6:00000000 D7:00000000 CR:0000
A0:00BFFFFC A1:00FF0264 A2:00000000 A3:00000000 A4:00E840C0 A5:00000000 A6:00001FFC A7:00001FFC SR:0020
<2479> (00FF023E ->) 00FF0244 : movea.l $8.l, A2
D0:FFFFFFFF D1:00008000 D2:00000000 D3:00000400 D4:00000000 D5:00000000 D6:00000000 D7:00000000 CR:0000
A0:00BFFFFC A1:00FF0264 A2:02FF0540 A3:00000000 A4:00E840C0 A5:00000000 A6:00001FFC A7:00001FFC SR:0020
<23C9> (00FF0244 ->) 00FF024A : move.l A1, $8.l
D0:FFFFFFFF D1:00008000 D2:00000000 D3:00000400 D4:00000000 D5:00000000 D6:00000000 D7:00000000 CR:0000
A0:00BFFFFC A1:00FF0264 A2:02FF0540 A3:00000000 A4:00E840C0 A5:00000000 A6:00001FFC A7:00001FFC SR:0020
<2650> (00FF024A ->) 00FF0250 : movea.l (A0), A3


あれ、addr=12582909って16進に直すと0xbffffdだが、トレースでみるとA0レジスタは0xbffffcだな。普通に偶数番地でアクセスしているのになぜバスエラーになる?

よくわからんのでソース確認。

まずデバッガでみると奇数番地でアクセスしている様に見えたのは以下のとおり、途中でaddr++しているのでそう見えただけ。実際にはトレース内のA0レジスタの値通り0xbffffcで偶数番地アクセスしている。

WORD FASTCALL
cpu_readmem24_word(DWORD addr)
{
(途中省略)
v = rm_main(addr++) << 8;
v |= rm_main(addr);
if (BusErrFlag & 1) {
Memory_ErrTrace();
BusError(addr, 0);
}
return v;
}


ではなぜバスエラーが起こる?それも答えはソースの中にありました。0xa00000から0xbfffffまでの番地へのアクセスはバスエラーになるのですね。

static BYTE FASTCALL
rm_main(DWORD addr)
{
BYTE v;

addr &= 0x00ffffff;
if (addr < 0x00a00000) { // RAM 10MB
v = MEM[addr ^ 1];
} else if (addr < 0x00c00000) {
rm_buserr(addr);
v = 0;
} else if (addr < 0x00e00000) {
v = GVRAM_Read(addr);
} else {
v = MemReadTable[(addr >> 13) & 0xff](addr);
}

return v;
}


なぜその番地にアクセスしてはいけないの?という疑問はありますがX68000とはそういうものなのでしょう。
それよりもなぜ386版コアのxkeropiではバスエラーが起きないのか?

うーむ、386版コアの方もトレースとって比較してみるか。

続く。


Comment

コメントの投稿


管理者にだけ表示を許可する

Trackback

http://hissorii.blog45.fc2.com/tb.php/218-efda8ca5

«  | HOME |  »

プロフィール

ひっそりぃ

Author:ひっそりぃ
Twitter:@hissorii_com
GitHub:hissorii


月別アーカイブ


最新記事


カテゴリ



最新コメント


最新トラックバック




RSSリンクの表示


Amazon


QRコード

QRコード

Amazon


ブログランキング

ブログランキング【くつろぐ】
にほんブログ村 ゲームブログ×PlayNCBlogへ

メールフォーム

名前:
メール:
件名:
本文:


カウンタ


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。