MYCPU80でCP/Mを!
超巨大基板の8080互換HCMOS・CPUでCP/Mを走らせてしまおうという、なんとも狂気なプロジェクトです!
[第23回]
●MEMRDは使えませんでした
[第21回]からの続きです。
あともう少し補足説明の追加をいたします。
MYCPU80から読み取ったアドレスバス、データバスなどのデータをメモリ(CY7C1347G)に書き込むときのタイミングパルスとして、当初はMEMRD、MEMWR、IORD、IOWRの各信号を使うように考えました。
ところが実際にやってみますとどうもおかしいのですね。
データが思うように記録されません。
MEMRDがうまく利いていないようです。
はて?
そこで、しばし沈思黙考。
おお。
やっと気が付きました。
普通のCPUと違って、MYCPU80ではメモリからの読み出しが連続して行なわれる場合には、MEMRDはその間は出っ放しになるのでした。
たとえばJMP命令(C3XXXX)の場合で考えてみますと、メモリからは3回の読み出し動作が行なわれます。
普通のCPUでは当然MEMRDパルスが3回出力されるのでありますが。
わがMYCPU80の場合には、その間は連続した1回のMEMRDが出されるのでした。
もう記憶も定かではないのですが、おそらくICをひとつでも減らしたいという切実な思いからだったでありましょうし、またたとえ毎回MEMRDを出力するようにしたとしても、何の得にもならないという考えからだったでありましょう。
しかし、こういう局面に出会ってみますと。
むむ。
普通のCPUではMEMRDが毎回律儀に出されていることには、それなりの意味があったのだなあ、とあらためて感じ入りました。
いやいや。
そんなところで感じ入ってみたってはじまりません。
MEMRDをなんとかしなければ。
そこで一計を案じました。
メモリからデータを読み出すときは、必ずOPcodefetchかregWRがアクティブになることに気が付きました。
メモリから読み込んだデータが命令の第一バイトであるならばそれはOPcodeですからOPcodeレジスタにラッチされます。
それ以外のデータならば、それは通常のレジスタか一時的に保存するためのワークレジスタにストレージされます。
OPcodefetchやregWRは書き込みパルスですからレジスタに書き込む都度パルスとして出されます。
ですからそれを利用してMEMRDとOPcodefetchかregWRのANDを取れば、結果としてMEMRDが1バイトごとに出力されたのと同様の信号として得られると考えました。
[第19回]の接続ケーブルのところの説明で「OPcodefetch信号とregWR信号があとから必要になったので」と書いたのはそういう理由からでした。
そのようにしたところ、やっとまともにデータが取れるようになりました。
しかし。
データは取れるようになったのでありますが…。
●記録したデータの解析は大仕事でありました
とりあえずということで記録したログファイルはなんと17MB以上もありました!
TXTファイルなのですが巨大すぎてメモ帳(notpad)などではとても開けません。
TeraPadでやっと開くことができました。
さすがTeraPadはすぐれものです。
冒頭部分です。
ログファイルとして記録されています。
このログファイルをずっと後ろのほうまで調べていきましたら。
●おかしなところがみつかりました
やっと。
みつけました。
120498行〜120500行は、アドレスバスは 021E〜0220 でデータバスは CA1602 (JZ 0216H) になっています。
ところがその次の120502行では、アドレスが 02F7 で、データバスは FF (RST7) になっています。
これはおかしい。
ここは条件ジャンプ命令ですから、条件が満たされたときはアドレス0216へ、条件不成立のときは次の0221へ行くべきところです。
なぜか、ここで突然暴走して関係の無いはずの02F7に飛んでしまっています。
でもこのデータからは、その理由、原因まではわかりません。
ただ現象がみつかった、というだけです。
すると、この次はその原因をさぐらなければなりません。
が。
しかし。
その問題はちょっと置いておくことにいたします。
その問題とは別に、私としましてはどうしてもけりをつけておかなければならない問題がありました。
あ。
それはそれといたしまして。
この120502行という数字にもぜひともご注目くださいませ。
記録の先頭の第13行からここまで、ずっとMYCPU80の動作が正しいかどうかアドレスとコードを確認しながら追跡してきたのでありますよ。
この暑い中で、そりゃああなた、並大抵のことじゃありませんですよ。
そこんところをわかってくださいまし。
ま。
実を申しますと、途中ところどころ飛ばしながら、アドレスが正常な範囲にあるかどうかを確認しつつ飛ばし読みで追跡いたしましたです。
いくらなんでも先頭から1バイトずつ確認していたのでは、寿命が尽きてしまいまする。
で。
120509行の、アドレス 3D02 つうのを見つけましたです。
TK−80モニタプログラムは0000〜02F3です。
アドレス3D02はありえません。
それでそこから前に追求していきました。
まあ、死ぬほどの苦労ではありませんでしたけれど。
それでもしっかり疲れましたです。
年寄りにはきつい作業でありました。
お話を元に戻しまして。
その120502行、アドレスが 02F7 で、データバスは FF (RST7) のところです。
ここはRST7ですから、次のリターン先アドレスをスタックにプッシュしたあと、アドレス0038にジャンプすべきところです。
そのあとの120503行〜120504行ではおそらくスタックと思われるメモリに次のアドレス(02F8)をプッシュしています。
そこまではRST7の動作としては正常です。
しかしその次の120505行ではなんと、アドレス 023A に飛んでしまい 2A023D が実行されています。
しかも実は、023AにあるのはOPコードではありません。
その部分のリストです。
; 0216 CD2302 KEYIN:CALL INPUT 0219 47 MOV B,A 021A 3AF3FF LDA KFLAG 021D A7 ANA A 021E CA1602 JZ KEYIN 0221 78 MOV A,B 0222 C9 RET ; ; KEY INPUT SUB ; 0223 CD4702 INPUT:CALL KEY 0226 3C INR A 0227 CA4202 JZ NOKEY 022A CDEA02 INPUT2:CALL D2 022D CD4702 CALL KEY 0230 47 MOV B,A 0231 3C INR A 0232 CA4202 JZ NOKEY 0235 3AF3FF LDA KFLAG 0238 A7 ANA A 0239 C22A02 JNZ INPUT2 023C 3D DCR A 023D 32F3FF INPUT3:STA KFLAG 0240 78 MOV A,B 0241 C9 RET 0242 06FF NOKEY:MVI B,FF 0244 C33D02 JMP INPUT3 ; |