標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第611回]
●RS232C受信プログラムにミスがありました
前回お見せしたBASICのRS232C受信プログラム(READ #命令)に、ミスがありました。
といって訂正したところで、なにやってるのかわかんないよー、ということなのでしょうけれど。
でも、間違いは間違いですので。
受信エラーが発生すると、SINERが実行されます。
前回のプログラムリストの終わりのところです。
下はエラーを修正したあとのリストです。
39E1 C1 SINER:POP BC;DUMMY =PC 39E2 C1 POP BC 39E3 D1 POP DE 39E4 E1 POP HL 39E5 77 LD (HL),A 39E6 23 INC HL 39E7 3600 LD (HL),00 39E9 3EEF LD A,EF 39EB D398 OUT (98),A 39ED 3E49 ER49:LD A,49 39EF C33631 JP ERRDP
エントリした最初のPOP命令が、
POP AF
POP AF
になっていました。
その下のところで、
LD (HL),A
を実行しているのですが、実はこのAレジスタには、エラーが発生したときのエラーコードが入っているのです。
それがPOP AFで消されてしまっておりました。
動作確認のために、わざとエラーを発生させてみたところ、プログラムミスに気がつきました。
やっぱりテストしてみるべきなのです。
わざとエラーを発生させてみた、プログラムと実行結果です。
10 ON ERROR GOTO 90 20 PRINT "START" 30 KETA%=0 40 READ #1,RDATA$,KETA% 50 IF KETA%<=0 GOTO 40 60 PRINT RDATA$; 70 IF RDATA$="END"THEN STOP 80 IF KETA%=40 GOTO 30 ELSE PRINT :GOTO 30 90 PRINT "err line=";ERL,"err=";ERR,"232c err=";KETA% >r. START err line=40 err=73 232c err=4
受信側のボーレートは9600ボーなのですが、そこにわざと2400ボーで送信してみました。
受信エラーが発生したときは、文字変数のバイト数を入れる整数型変数(上のプログラム例ではKETA%)に、エラー種別が入ります。232C err=4になっています。フレーミングエラーです。
ERLはエラーが発生した行番号、ERRはエラーコードが格納されるシステム変数です。
エラーコード73は232C受信エラーです。
●ND80ZVのLEDに05C0が表示されてしまうことについて(解決編です)
前回は飛び入りで横道にそれてしまいました。
[第609回]からの続きです。
ディップスイッチがSTEP側になっている状態で、リモート接続を終了すると、ND80ZVの7セグメントLEDに05C0xxxxと表示されてしまうことについて、すこし糸がほぐれてきました。
表示のされ方からすると、どうもアドレス05C0で割込みによってブレイクしているようなのです。
リモート接続を終了するときに、ND80ZVをソフトウェア的にリセットするために、[0][0][0][0][ADRSSET][RUN]のキーコードを送りますが、そこでEI命令が実行されて、割込み許可状態になってしまうことがわかりました。
しかし、LEDに表示される05C0はROMのアドレスですから、そこで割込みが発生してブレイクするというのはちょいとおかしい…。
と、最初は考えていたのですが、そこにも思い込みがありました。
ND80Zモニタのステップ、ブレイク動作(TK80モニタの動作も同じ)で表示されるアドレスはブレイクしたアドレスではなくて、ブレイクしたときに次に実行されるアドレスなのでした。
つまり05C0はまだ実行されてなくて、ブレイクしたのは、05C0の直前に実行されたアドレスだったのです。
0000番地にジャンプしたあとで、実行されるモニタプログラムの流れを調べてみました。
すると。
おお。
みつかったのです。
モニタプログラムの中でRAMアドレスを実行している部分が。
0866 21C005 NDMON3:LD HL,LEDDPA 0869 22CAFF LD (RST6JA),HL 086C 211606 LD HL,KEYINA 086F 22C7FF LD (RST5JA),HL 0872 215104 LD HL,TK2RST1 0875 22BBFF LD (RST1JA),HL ; 0878 21D209 LD HL,BREAK 087B 22CDFF LD (RST7JA),HL 087E 21CFFF LD HL,RMODE 0881 0629 LD B,29 0883 AF XOR A 0884 77 LD (HL),A 0885 23 INC HL 0886 10FC DJNZ FC 0888 2100F8 LD HL,USTOP 088B 22E2FF LD (SPL),HL ; 088E 3EFF START1:LD A,FF 0890 D398 OUT (98),A 0892 31B8FF LD SP,SPTOP 0895 CDC9FF CALL LEDDP 0898 CDC6FF START2:CALL KEYIN
ND80Zモニタプログラムのエントリ部分です。
アドレス0000からスタートしたあとは、ここへ来ます。
アドレス0895のCALL LEDDPのマシン語コードが、CDC9FFになっています。
FFC9番地をCALLしています。
RAMのアドレスです。
FFC9には何があるのでしょうか。
実は、上のリストの先頭部分、アドレス0866を見ますと
FFCAに05C0を入れています。
ここでは見えませんが、もう少し前のところで、FFC9にはC3を書いています。
つまり、RAMアドレスFFC9には、C3C005という命令が書かれていたのです。
なぜこのような面倒なことをしているかと言いますと、この部分(LED表示をする部分)が、リモート接続されたときは、LED表示をすると同時に、USB経由で表示データをWindowsパソコンに送るためのプログラムと置きかえることができるようにするためです。
これでやっと謎が解けました。
リモート接続を終了するときに、ND80ZVをソフトウェア的にリセットするために、[0][0][0][0][ADRSSET][RUN]のキーコードが送られ、そこでEI命令が実行されて、割込み許可状態になります。
しかし、0000番地からスタートしたあとは、ROMアドレスに書かれている命令を実行しますから、割込みは発生しません。
ところが上のリストのアドレス0895のCDC9FFが実行されると、次にRAMアドレスFFC9に書かれている命令、C3C005が実行されます。
その直後に割込みが発生して、その次に実行されるアドレス05C0が表示されることになったのです。
●RUNルーチンを直しました
原因がわかれば対策は立てられます。
しばらくどうするのがよいか考えていたのですが、最も簡単、easyな方法を思いつきました。
普通のRUN動作は、RAMアドレスにジャンプしたときにステップ動作や、ブレイク動作ができるように、EI命令を実行して、割込みが受付けられる状態にします。
そこのところを、アドレス0000に対するRUNのときだけ、逆にDI命令を実行して、割込みを禁止するようにすればよいはずです。
下がそのように追加を行ったプログラムリストです。
; RUN 09A6 2AEEFF RUN:LD HL,(ADRSL) 09A9 22E0FF LD (PCL),HL 09AC 7C LD A,H 09AD B5 OR L 09AE F3 DI 09AF CA0000 JP Z,$0000 ; ; CONTINUE 09B2 31D4FF CONT:LD SP,LDSH 09B5 E1 POP HL 09B6 D1 POP DE 09B7 C1 POP BC 09B8 D9 EXX 09B9 F1 POP AF 09BA 08 EX AF,AF' 09BB FDE1 POP IY 09BD DDE1 POP IX 09BF 31E6FF LD SP,EREG 09C2 D1 POP DE 09C3 C1 POP BC 09C4 F1 POP AF 09C5 ED7BE2FF LD SP,(SPL) 09C9 2AE0FF LD HL,(PCL) 09CC E5 PUSH HL 09CD 2AE4FF LD HL,(LREG) 09D0 FB EI 09D1 C9 RET ;
このように変更したところ、ディップスイッチがSTEP側のときに、リモート接続を終了しても、ND80ZVの7セグメントLEDには、STEP側にしていないときと同じように、00000000が表示されるようになりました。
めでたし、めでたし、と言いたいところなのですが、まだ問題が残っていました。
そうでした。
一番最初に、リモート接続してから、ディップスイッチをSTEP側にして、[8][0][0][0]と入力しようとしたところ、[8]を入力した直後に(多分)ブレイクしてレジスタダンプ表示が出たことについては、きちんと説明がつくのでしょうか。
今回は時間がなくなってしまいましたので、そのことにつきましては、次回に説明をすることにいたします。
2010.9.15upload
前へ
次へ
ホームページトップへ戻る