Ten little endian boys Part 2 (フォンノイマン・ボトルネックを回避したい)
前回の記事の続きです。
前回はリトルエンディアンマシンでビッグエンディアンマシンをエミュレートする際のフォンノイマン・ボトルネックの話で終わってしまったわけですが、X68000エミュレータであるkeropiがこれをどのように回避しようと頑張っているのか、今回は実際にソースを追っていきたいと思います。
まずはひっそりぃがxkeropiのソースを読んでいて、最初に「なんぞこれ?」と思った箇所です。x11/winx68k.cpp内のWinX68k_LoadROMs()という関数内ですが、X68000のBIOSデータiplrom.datの内容をメモリIPL[]に読み込んだ直後の以下の処理です。
これは例えば「AA BB CC DD EE FF」というメモリ内容を「BB AA DD CC FF EE」といった内容に並べ替える処理を行っています。
はじめはビッグエンディアンのBIOS情報をファイルiplrom.dat上ではリトルエンディアンで記録していたので、元に戻しているのかと思いましたが、ソースを読み進むうちに、どうやら違うことに気が付きました。
実際にMC68000の命令をメモリからフェッチして、フェッチした命令の処理に分岐させる以下の箇所になります。x11/68kem.asm内の_M68KRUN:です。
前回はリトルエンディアンマシンでビッグエンディアンマシンをエミュレートする際のフォンノイマン・ボトルネックの話で終わってしまったわけですが、X68000エミュレータであるkeropiがこれをどのように回避しようと頑張っているのか、今回は実際にソースを追っていきたいと思います。
まずはひっそりぃがxkeropiのソースを読んでいて、最初に「なんぞこれ?」と思った箇所です。x11/winx68k.cpp内のWinX68k_LoadROMs()という関数内ですが、X68000のBIOSデータiplrom.datの内容をメモリIPL[]に読み込んだ直後の以下の処理です。
おもむろにメモリIPL[]の内容を並べ替えています。for (i = 0; i < 0x40000; i += 2) {
tmp = IPL[i];
IPL[i] = IPL[i + 1];
IPL[i + 1] = tmp;
}
これは例えば「AA BB CC DD EE FF」というメモリ内容を「BB AA DD CC FF EE」といった内容に並べ替える処理を行っています。
はじめはビッグエンディアンのBIOS情報をファイルiplrom.dat上ではリトルエンディアンで記録していたので、元に戻しているのかと思いましたが、ソースを読み進むうちに、どうやら違うことに気が付きました。
実際にMC68000の命令をメモリからフェッチして、フェッチした命令の処理に分岐させる以下の箇所になります。x11/68kem.asm内の_M68KRUN:です。
いきなり80386アセンブリで申し訳ないですが、ひっそりぃもZ80のアセンブリしか知らないので、ノリで読んでいきましょう。_M68KRUN:
pushad
mov esi,[R_PC]
mov edx,[R_CCR]
mov ebp,dword [_OP_ROM]
(途中省略)
movzx ecx,word [esi+ebp]
jmp [OPCODETABLE+ecx*4]
スポンサーサイト