標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第252回]
●RETキーがおかしい?
お話はTK80のモニタプログラムを初めてRAMにセットアップしたときまでさかのぼります。
といいますと、[第235回]のころということになります。
「とんでもないミスをみつけてしまいました」と書いています。
記事は現実にことが起きたときよりもあとで書いていますから、時として話が前後しているような書き方になってしまうこともあります。
[第239回]で、「RETキーがおかしい」と書いています。
今回、やっとそのことについての説明までたどりつきました。
なにしろ「ステップ動作」のテストをしたときに、「RETキーがおかしい」ことに気がついたものですから、どこがどうおかしいのか、それを説明するためには、まず「ステップ動作」やら「割り込み」やらについて説明をする必要があったのです。
それで、こんなに遅くなってしまいました。
さて、そこで、そのRETキーの動作です。
ステップ動作をテストするために、RETキーを押してみました。
そうしたら。
あれ?おかしい…?
最初にRUNキーを押したときには、ちゃんと1命令だけ実行して、そこでブレイクして、モニタプログラムに戻ってきたのに、その次に、RETキーを押したら、今度はブレイクしないで、ステップ動作が無視されて、なんだか連続実行してしまっているみたいなのです。
状態としては、どうも割込みが利いていないような…。
割込みがからんでいるようなトラブルでのデバッグは大変です。
ホネが折れます。
最初は当然のことながら、モニタプログラムを疑いました。
移植の過程でどこか、ソースプログラムにミスがあったのでは?
当然、RETキーのルーチンが一番おかしい、はず。
ところが、ここで、また、はたと悩んでしまいました。
RETキーのルーチンはすでにお見せしています。
01F9から始まるプログラムでした。
;
; REGISTER RESTORE
;
01F9 2AE2FF RESRG:LHLD SSAVE
01FC F9 SPHL
01FD 2AE0FF LHLD PSAVE
0200 E5 PUSH H
0201 2AE4FF LHLD LSAVE
0204 E5 PUSH H
0205 2AEAFF LHLD FSAVE
0208 E5 PUSH H
0209 2AE8FF LHLD CSAVE
020C 4D MOV C,L
020D 44 MOV B,H
020E 2AE6FF LHLD ESAVE
0211 EB XCHG
0212 F1 POP PSW
0213 E1 POP H
0214 FB EI
0215 C9 RET
RETキーを押すと、直接このルーチンにジャンプしてくることは、前回([第251回])説明いたしました。
ところが、ところがです。
このRESRGは、なんとRUNキーでも使われているのです!
RUNキーが押されると、00CCにジャンプする、ということも前回説明をいたしました。
;
; MONITOR TO USER CONTROL ROUTINE
;
00CC 2AEEFF GOTO:LHLD ADRES
00CF 22E0FF SHLD PSAVE
00D2 C3F901 JMP RESRG
見ていただいての通りです。
RUNキーの動作は、RETキーの動作の全てを含んでいるのです。
RUNキーとRETキーの違いは、ただの1箇所だけです。
RETキーは、PSEVEに保存されていた戻り先アドレスをプログラムカウンタにセットしてリターンします。
RUNキーはLEDのアドレス表示部に表示されているアドレスをPSAVEに保存したあと、上記のRETキールーチンにジャンプします。
基本的には、全く同じ、じゃありませんか!
なのに、どーいうわけか、RETキーだと、動作がおかしくなってしまうのです。
まあ、たしかに、変更、追加の連続で、くもの巣状態の配線になっていますから、誤動作したっておかしくはありませんけれど。
ただ、そういう原因での誤動作ならば、もっとランダムな出方をするはずです。
ほかのキーの動作は(といっても、ほかにもこの時点では試していないキーもあったのですけれど)なんともなくて、RETキーに限って必ずおかしい、というのは、確かにおかしい。
そこで、徹底的に追求してみることにしました。
やれやれ、全くストレスの多いことです。
割込みがからんでいるとなると、デバッグはなかなかに面倒です(結果的には、割込みとは無関係だったのですが)。
おお。そうだ。
こんなときに、レジスタの値が全部LEDに表示されている、というのはまことに好都合です。
幸い、モニタプログラムはROMではなくて、まだRAMに書き込んでのテスト作業中です。
想定されるプログラムの流れで、ポイントになる部分の命令をHLT(命令コード76)に書き換えて、テストしてみました。
すると。
信じられないことがおきたのです。
RETキーを押したのに、RETキールーチンがパスされてしまう!
RETキーを押したら、ダイレクトに01F9にジャンプするはずなのに、01F9にはジャンプしていない!
そんな、ばかな!
こうなると、あやしいのは、キー入力コードをもとにジャンプテーブルを参照している、あのルーチンです(前回、説明した0051からのスタートルーチンです)。
そこでジャンプテーブルからジャンプ先アドレスをHLに入れた直後のところにHLT命令(76)を書き込んで、テストしてみました。
前回お見せしたモニタスタートルーチンのキーコードからジャンプ先アドレスを求める部分のプログラムです。
0064 78 MOV A,B
0065 E60F ANI 0F
0067 0600 MVI B,00
0069 87 ADD A
006A 4F MOV C,A
006B 217400 LXI H,TABL
006E 09 DAD B
006F 7E MOV A,M
0070 23 INX H
0071 66 MOV H,M
0072 6F MOV L,A
0073 E9 PCHL
;
0074 CC00 TABL:DW GOTO
0076 F901 DW RESRG
0078 9400 DW ADSET
007A B800 DW ADDCX
007C 9D00 DW ADINX
007E C200 DW MEMW
0080 D500 DW SDATA
0082 0701 DW LDATA
;
このプログラムの
0073 E9 PCHL
を、
0073 76 HLT
に書き換えて、RETキーを押してみたのです。
そうしたら。
なんと!信じられないことに、HLレジスタにはジャンプテーブルのRETキーへのアドレス、01F9が入らなくてはいけないのに、全く異なる値が入ってしまっていたのです。
何回繰り返してみても、結果は同じでした。
もっと正確にいうと、おかしいのは決まってHレジスタの値なのです。
LレジスタにはちゃんとF9が入ります。
Hレジスタに01以外の変な値がセットされてしまうものだから、関係無いところにジャンプしてしまっていたのです。
なぜ?
どうして、Hレジスタに変な値が入ってしまうのか?
プログラムを、そして回路図を見比べて、あっちを見たり、こっちを見たり、しているうちに…。
やっと。
気がつきました。
とんでもない、おばかな回路ミスをしでかしていたことに…!
聡明な読者の中には、すでにお気づきになられた方もいらっしゃるかもしれません。
問題は、MOV H,Mにありました。
何が問題なのか、それを解くカギは[第233回]にあります。
2009.6.17upload
前へ
次へ
ホームページトップへ戻る