2015年04月20日

BUSエラー

割り込み処理等も追加し、FDCも接続してそろそろHuman68kの動作画面が
見られるかな?と思っているのですが、なかなかそうもいかないようです。
MC68000には例外処理としてBUSエラーという物が有るようです。
メモリが存在しないアドレスに対し読み書き等を行った時に発生する
例外のようです。
DE0は8MbyteのSDRAMを実装しており、テキストとグラフィックス用の
VRAMに計1Mbyteを使用するため、残りの7Mbyteをメインメモリに
割り振っています。
従い、7Mbyte以降、IOエリア未満のアドレスにはメモリがマッピング
されていない為、この領域にアクセスした場合にはバスエラーを発生させる必要が
有ります。
ですが、今回使用しているMC68000互換IP、TG68にはバスエラー入力が有りません。

以前書いたように、TG68には割り込みもオートベクタしかない為、ベクタ割り込みには
対応していません。その為、外部回路で割り込み応答時のベクタ読み出しに対し、
アドレス変換を行いベクタ割り込み用のアドレスを読ませることで対応しました。
この部分はちゃんと動作しているようですので、バスエラーも同じように割り込みで
代替出来ないか、と考えてみました。

バスエラー時の例外ベクタは$02です。割り込み禁止状態でも反応しないと困る為、
NMI(INT7)のベクタであるベクタ$1fの読み出しに対し、バスエラー状態であれば
ベクタ$02のアドレス($000008~$00000b)のメモリをアクセスするようにしています。

ですが、どうもうまく動いていないようです。どうも、MC68000のデータシートを読むと、
バスエラー時のスタックに積む内容と、通常の割り込みでスタックに積む内容が
全然異なるようです。
通常の割り込み時には、プログラムカウンタの値とステータスレジスタのみ
スタックに積むようですが、バスエラー時には更に読み書きのどちらで発生したのか、
どのアドレスに対して発生したのか、どの命令で発生したのか等の情報も
スタックに積むようです。
これを外部で回路として処理するのは簡単ではなさそうです。さて、困りました。

どうやら、バスエラーはBIOSの中で意図的に発生させているようです。
バスエラーの発生する直前にSRAMから値を読み出し、そのアドレスを読み出す
処理を行っていますが、そのアドレスがメインメモリ範囲の最終アドレス、
$bffffe番地です。何故このアドレスの指定になっているのかは分かりませんが
SRAMの初期値がこのアドレスのようです。
このSRAMに書かれたアドレスを実在するアドレスに変更すればとりあえずは
バスエラーは発生しなくはなりそうですが、何の為のアドレスで、どのような
値を設定したら良いのかわかりません。
ネットで検索した範囲では、ROMの開始アドレスとのことですが。。。?

どのように対処したらうまくいくのでしょうか。
MPUのIPを別のものに変える必要が有るのでしょうか。
他にもMC68000にはいろいろな例外が定義されていますが、該当処理
と思われる部分のTG68のRTLは結構虫食いになっているようです。。。
posted by プー at 20:17| Comment(7) | X68000 | 更新情報をチェックする
この記事へのコメント
お久しぶりです
さて68000ですが、かつてMacで使っていて仕事をしたこともあるので一つ。
TG68は歯抜けですね。単純なコードは動くでしょうけどOSはダメな気がします。

まずWikiのMC68000の項は読みましたか?
ja.wikipedia.org/wiki/MC68000

バスエラー時にスタックに積む内容が多いのはエラー処理や復帰のためです。
他のエラー(トラップ)でも同様です。
MacOSでは爆弾が出ます(爆弾が出なくなって久しいので最近は見たことない人も多い
ですが)。

$(00)bffffeはRAMの上限アドレスです。
メモリマップは↓を参考にしましたが、サービスマニュアルのが良さそうです。
www.ne.jp/asahi/pursuits/ootsuki/pc/X68k/x68k_doc_memap.html
www.jcec.co.uk/J_X68000_Emulator_resources.htm

デバッガ内蔵のX68kエミュレータがあった気がします。

# X68000の時点でI/Oアドレスを$(00)c00000~ではなく$(ff)c00000~にしておけば
# 68030採用の際に16Mの壁ができなかったような気がしますが、後の祭りですね
# このように実装していない空間を0か1に固定する方式は今日のAMD64/Intel64が
# 採用しています。
# ちなみに、Macでは24ビットモードと32ビットモードでI/Oアドレスがガラッと
# 変わります
Posted by かかっくん at 2015年04月22日 00:15
とりあえずSRAMの該当アドレスが初期値だと
RAMfull実装時の最終アドレスで、
わざわざBUS errorを起こさせるようですが、
ここにROMDISKのアドレスを書き込むと
ROMDIKからbootするらしいので、
今はそうしています。
FDDを0シークし、完了の割り込みルーチンで
永久ループにはいってしまう、という所を現在デバグ中。
BIOSを逆アセンブルしても、どうやってもループから
抜け出す方法がわかりません。。。
Posted by プー at 2015年04月29日 00:20
> とりあえずSRAMの該当アドレスが初期値だと
> RAMfull実装時の最終アドレスで、
> わざわざBUS errorを起こさせるようですが、
> ここにROMDISKのアドレスを書き込むと
> ROMDIKからbootするらしいので、
> 今はそうしています。

トラップという事はどこかへ飛ぶワケですから(HALTするワケではないので)、エミュ
レータで飛び先を追ってみると解りそうです。RAMを12Mにした場合と他でどう挙動が
違うかで解りそうです。

XEiJとかXM6iはいかが?
stdkmd.com/xeij/
xm6i.org/

> FDDを0シークし、完了の割り込みルーチンで
> 永久ループにはいってしまう、という所を現在デバグ中。
> BIOSを逆アセンブルしても、どうやってもループから
> 抜け出す方法がわかりません。。。

抜けるのも何かの割り込みでは?

あと、OSやアプリケーションがIOCS(API)でFライン(X68030やMacはAライン)トラップを
多用していますが、トラップのルーチンを省いても平気ですか?

I/Oアドレスの件はMacにもいえる話でした。Macの場合は元祖から3年(128K→MacII)で
32ビット化した(X68000→X68030は発売ベースで6年)ので、最大RAM8Mがネックでした。
(解決まで4年、System6.xの目玉機能のMultiFinderが24ビット、RAM8Mでしか使えなかっ
たのが大いなる欠点)その間アーキテクチャが若干異なるPortable(最大9M)やLC(最大
10M)などの例外はありましたが、本流はQuadraやSystem7が出るまで8Mどまりでした。
Macが出た'84には68020が出ましたから、512KやPlusあたりで対策を取り込めたような...

ところで、日本内外でTG68を使ったMacやATARI・Amigaを実装した例ってありましたっ
け?
Posted by かかっくん at 2015年04月29日 23:41
エミュレータ関係はまた今度やって見ます。88の時はM88の強力なデバグ機能が
とても役に立ったので同じような機能があると助かります。

永久ループの関係はやっと解決しました。というのも、uPD72065(uPD765もかな?)は
割り込みが掛かっていない状態でSENSE INTERRUPT STATUSを実行すると
ST0に0x80(コマンド無効)を返すのですね。uPD765の英文データシートには記載がありませんでした。
割込み処理に入り、SENSE INTERRUPT STATUSを発行しますが、それを
ST0が0x80を返すまでループする、となっています。
SENSE INTERRUPT STATUS自体は実在するコマンドなので常に有効コマンドとして
返していたため永久ループに入っていたようです。
割込み後2回目以降のSENSE INTERRUPT STATUSコマンドにはST0で0x80を返すように
変更したところ、このループから抜けることができました。
Posted by プー at 2015年04月30日 01:18
忘れていました。
X68030用のROMとHuman68k(2.15以降)を使ってみて下さい。
Wikiの68020の項の命令セットの節の最後の段落の
---
なお、F(1111)ラインエミュレータにおいて、メモリを参照するオペコードを実行した場合、メモリーへの投機実行が行われる。この為、1111ラインエミュレータにシステムコールを配置したOS(例えばシャープ/ハドソン Human68kのVer.2.0以前)では予期せぬメモリアクセスによってバスエラーが発生するという問題が生じた。この問題はA(1010)ラインエミュレータでは発生しない。
---
に該当するような気がしたので。もしこれに該当する場合は本来の68000コアではなく
'020/030コアという事ですから、コアの修正が必要です。つまりFラインに関しては
68000/010と'020以降で互換性がないという事です。
ja.wikipedia.org/wiki/MC68020
Posted by かかっくん at 2015年04月30日 02:22
SENSE INTERRUPT STATUSについてですが、μPD72070のアプリ
ケーションノート(IEA-751)の5ページ(PDF 20)に書いてありました。
---
μPD72070のDKCG/READY端子をディスク・チェンジ信号で使用する場合,μPD72070の内部で
READY信号が常にアクティブになるため,μPD72070をリセット(ハードウエア/ソフトウエ
ア・リセット)した場合,ドライブ4台分の状態遷移割り込みが発生します。
イニシャライズ時は,SENSE INTERRUPT STATUSコマンドを発行し,コマンドがINVALID
COMMAND(ST0 = 80H)になるまで発行を繰り返してください。
---
IEA-751.pdfで検索下さい
探せば765や72065のアプリケーションノートも見つかるかも知れません。
Posted by かかっくん at 2015年04月30日 04:29
あと、TH68のコードを見た範囲では、Fライントラップ等、一部の例外処理は
考慮されており、特にソフトウェア関連の例外は比較的準備されているようです。
Posted by プー at 2015年04月30日 06:55
コメントを書く
コチラをクリックしてください