まったりと車体を組み中。ちょこっと作業してはマクガイバー見たり、ちょう
どamazonで注文しておいたマイアミバイスがやってきたので、まだそれを見て
で進まない。
マイアミバイスは実は見たことがない。ちょこっと見たことはあるのだけれど、 居間のテレビで見るにはちょっと刺激が強いシーンも多いので、見れなかった ^^。
残念なことに、今回僕が買ったマイアミバイスは吹き替えがなかった。それに これレンタル用だし。
「 VIPPER刑事物語 やる夫とやらない夫 」このやる夫 版は、原作を噛みくだいた上で、ストーリーに乗りながら、いいアレンジでと てもいい。というか、こっちの方がストーリーとしては好きかな。日本人向け なのか。
あと「ダウリング神父」がもう一度見たい。残念ながらDVD化されてないようだ。 シスター・ステファニー、好きだったんだ。神父の下の男が吹き替えだと、確 か美味しんぼの富井副部長。ネーティブの声は結構渋くてギャップがすごかっ たのが忘れられない。

それはともかく。フォークオイルが真っ黒でした。あれ...なんでだと思ったら、 前にフォークをバラしたのは予備のフォークで(10月)、このフォークは去年の 8月以来だった。お恥かしい...。

x86続き。
マイアミバイスは実は見たことがない。ちょこっと見たことはあるのだけれど、 居間のテレビで見るにはちょっと刺激が強いシーンも多いので、見れなかった ^^。
残念なことに、今回僕が買ったマイアミバイスは吹き替えがなかった。それに これレンタル用だし。
「 VIPPER刑事物語 やる夫とやらない夫 」このやる夫 版は、原作を噛みくだいた上で、ストーリーに乗りながら、いいアレンジでと てもいい。というか、こっちの方がストーリーとしては好きかな。日本人向け なのか。
あと「ダウリング神父」がもう一度見たい。残念ながらDVD化されてないようだ。 シスター・ステファニー、好きだったんだ。神父の下の男が吹き替えだと、確 か美味しんぼの富井副部長。ネーティブの声は結構渋くてギャップがすごかっ たのが忘れられない。

それはともかく。フォークオイルが真っ黒でした。あれ...なんでだと思ったら、 前にフォークをバラしたのは予備のフォークで(10月)、このフォークは去年の 8月以来だった。お恥かしい...。

x86続き。
嫌なバグに悩まされた。0x0:0x8000に二段目をロードした後、メモリが破壊
されるのだ。つきとめていったところ、スタックの設定を間違えていた。
今迄
movw _stack_start, %sp
になっていた。これでは_stack_startのアドレスにある値がspになってしまう。
movw $_stack_start, %sp
じゃないといけなかった。_stack_startはldscriptで設定。
偶然、_stack_startには0xfff6が入っていたので、そこそこ動いていた。
リアルモードなら16bitだし、0xfff6でも動きそうなものだけど、どうも4byte
アラインじゃないとだめみたい。
昨日のような実験を元に保護モードのデスクリプタの設定は普通に設定して
先に進めます。ベースは0から。スタックセグメントもデータセグメントと
同じ設定で。
保護モードに入ってしまうと、そのままBIOSコールは呼びだせない(BIOSはリア
ルモードで呼ばれるのを前提としているので)。なのでデバッグ用にprintfを作
りました。これはH8で作ったやつをコピペで。
やっとA20のテスト。QEMUはデフォルトでA20は有効なので何もすることがない。
ので、あえて無効にしてテスト。
#define inb(addr, val) __asm volatile \
("inb %1, %0" : "=a"(val) : "d"((uint16_t)addr))
#define outb(addr, val) __asm volatile \
("outb %0, %1" :: "a"((uint8_t)val), "d"((uint16_t)addr))
x86はオペランドにレジスタの制限があるのでgasでもコンストレイントを
指定できるようになっている。幅はキャストで効く。
void
a20_test ()
{
uint32_t m0, m1;
uint8_t r0;
// make sure that i/o buffer is empty.
do
{
inb (0x60, r0); // drain buffer
inb (0x64, r0); // get status
}
while (r0 & 0x01); // output(i8042) buffer full
do
{
inb (0x64, r0);
}
while (r0 & 0x02); // input(i8042) Buffer Full
outb (0x64, 0xd0); // output port read command.
inb (0x60, r0); // read output port.
printf1 ("i8042 output port:%x\n", r0);
outb(0x64, 0xd1); // output port write command.
outb(0x60, 0x01); // write to output port. ここでA20を無効に。
// bit 0 ... RESET if set 0.
// bit 1 ... A20 disabled if set 0.
printf1 ("%x\n", r0);
// 0x200なのはリアルモードの割り込みハンドラのその先を設定。一応。
m0 = *(uint32_t *)0x200;
//A20が無効なら、この操作で0x200も書き変わるはず。
*(uint32_t *)((1 << 20) + 0x200) = m0 ^ 0xa5a5a5a5;
// __asm volatile ("wbinvd");
m1 = *(uint32_t *)0x200;
printf1 ("%x %x\n", m0, m1);
if (m1 != m0)
{
printf1 ("A20 disabled\n");これが表示されればA20は無効だ。
*(uint32_t *)0x200 = m0; // restore.
}
else
{
printf1 ("A20 enabled\n");
}
}
これでA20のスイッチをテスト。これはQEMU上では想定通りの動き。これを
ML115 G5の実機で動かしてみたところ、A20は有効のままだった。
さすがに今はもうこのあたりは削ったようだ。
