標準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

前へ
次へ
ホームページトップへ戻る