究極のWindows用PC-9821を求めて
最終更新日時 2006.11.11
CPUのL2チェッカを改変してTualatinも載るようになったRvII26ですが、もうひとつ大きな不満があります。
それは「メモリカウントが非常に遅い」コト。
ということで今回はメモリチェックの簡素化による高速終了を目指します。
メモリチェックもITF内の処理なので前回同様BANK4.BINを解析します。
ですが、範囲が広く一箇所にまとまっていないので余り詳しく解説できません(謝
ポイントのみを例示していくことにするのでご勘弁ください。
メモリチェックの基本ルーチンは
:0E5B B80800 mov ax,0008 ; メモリチェックループ前処理 :0E5E 8ED8 mov ds,ax :0E60 C606440010 mov byte ptr [0044],10 :0E65 C606470000 mov byte ptr [0047],00 :0E6A 66BA00001000 mov edx,00100000 :0E70 8AF7 mov dh,bh :0E72 B008 mov al,08 ; メモリチェックループ入り口 :0E74 E637 out 37,al ; パリティチェック有効:8255コマンド から :0FF2 668BC2 mov eax,edx :0FF5 66C1E810 shr eax,10 :0FF9 3DF0FF cmp ax,FFF0 ; チェック終了? :0FFC 7303 jnb 1001 ; (YES)ループ終了 :0FFE E971FE jmp 0E72 ; (NO )チェック継続
のループが主となっています。(もちろんこの後もECCチェック等あるのですが)
よって、このループの中で行われている処理を簡略化すればメモリチェックも高速になるというわけですね。
ではさっそく始めます。
PC-9821のメモリチェックは、128KBごとのチェックポイントに対しデータの書き込みと検証を行うことが基本になっています。
そこでこのチェック間隔を広げることでループ回数を減らそうという考えです。
N.Y氏のサイトにもありますが
:0FA2 B80800 mov ax,0008 :0FA5 8ED8 mov ds,ax :0FA7 8006440002 add byte ptr [0044],02 :0FAC 8016470000 adc byte ptr [0047],00 :0FB1 6681C200000200 add edx,00020000 :0FB8 B070 mov al,70 :0FBA E6A1 out A1,al :0FBC B057 mov al,57 :0FBE E6A3 out A3,al :0FC0 B020 mov al,20 :0FC2 E6A5 out A5,al :0FC4 E4A9 in al,A9 :0FC6 A880 test al,80 :0FC8 BCCE0F mov sp,0FCE :0FCB E96BFC jmp 0C39 :0FCE EB22 jmp 0FF2 :0FD0 90 nop
ここがそうで、このロジックで次のチェック位置を決定しています。
0044h〜0048hがワークエリアでlong形式のデータとして格納され、同じ内容がedxレジスタにも入ります。
よって[0044]に加算している02hとedxレジスタに加えている00020000hを変更すればOKです。
8倍速なので02=>10、00020000=>00100000です。
しかし、これだけではカウント終了後に再びカウントが始まってしまいます。
これを回避するにはPCIレジスタのエラー通知を不可にする必要があります。
powerx氏の掲示板でまりも氏が解説してくれていますのでご覧になってください。
実際の修正ポイントは
:42A8 4600FC db 46h,00h,0FCh ; REG 46の設定値 FC=>F8 :4323 4600FC db 46h,00h,0FCh ; REG 46の設定値 FC=>F8
の2箇所あります。
さらにもう一か所、レジスタ47hをチェックしているルーチンがあります。
:1E6E A804 test al,04 :1E70 241B and al,1B ; REG 47hのエラー検出を潰す :1E72 FFE5 jmp bp
これでOKですね。
上記処理を施した場合、512MB搭載で約20秒になるかと思います。
実際、SCSI機器のスピンアップを待つ時間もあるのでこれでも良いと思いますが、もう少し早くしたい気分です。
powerx氏のサイトやN.Y氏のサイトではメモリーフィルと確認ルーチンをパスする手法が記載されていますが、nicoは別のアプローチでやりました。
:0EEC 6633C0 xor eax,eax :0EEF 6766268947F4 mov es:[edi-0C],eax :0EF5 66B801000000 mov eax,00000001 :0EFB 6766268907 mov es:[edi],eax :0F00 66F7D0 not eax :0F03 6766268947F4 mov es:[edi-0C],eax :0F09 66F7D0 not eax :0F0C 6766263907 cmp es:[edi],eax :0F11 7407 jz 0F1A :0F13 6683C704 add edi,+04 :0F17 E92301 jmp 103D :0F1A 66F7D0 not eax :0F1D 6766263947F4 cmp es:[edi-0C],eax :0F23 7407 jz 0F2C :0F25 6683EF08 sub edi,+08 :0F29 E91101 jmp 103D :0F2C 66F7D0 not eax :0F2F 66D1E0 shl eax,01 :0F32 73C7 jnb 0EFB というチェックを :0F32 7200 jb 0F34 としてループしないよう変更し、 :0F34 B009 mov al,09 :0F36 E637 out 37,al の後を :0F38 EB68 jmp 0FA2 としてスキップしました。
これで更に3倍程度早くなります。
512MB実装で約7秒。なかなか気分が良いものです