標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第250回]
●TK80のステップ動作(モニタプログラム)の説明(続き)です
前回はTK80のステップ動作を、ソフトウェアの面から説明することにいたしました。
でも時間が足りなくなって、途中で終わってしまいました。
今回はその続きです。
TK80のステップ動作はRST7割込みを利用しています。
RST7割込みは、INT信号の入力によって、0038番地からのプログラムがCALLされます。
TK80モニタプログラムの0038番地には、0151へのJMP命令が書いてありますので、データバスになにものせないでINT信号だけが入力される(RST7割込み)と、結局0151からのプログラムが実行されることになります。
前回はその0151からのプログラムの始めの部分を説明しました。
この0151からのプログラムは、「ワンステップ動作」のプログラムです、と紹介しましたが、じつは「ワンステップ」動作というよりも、「ブレイク」動作、と言った方が適切だと思います。
ブレイク動作というのは、プログラムの実行中に、指定した条件によって、実行を中断してモニタプログラム(システムプログラム)に戻ることを言います。
パソコンなどでも「システムブレイク」などという言葉を使ったりしていますね。
TK80のステップ動作というのは、ブレイク動作を1命令ごとに繰り返し行っているものだとも言えます。
ユーザープログラムを1命令だけ実行した直後に「ブレイク」すると、この0151番地からのプログラムが実行されます。
前回は、その入り口部分で、CPUのレジスタやフラグ、プログラムカウンタ、スタックポインタの値をメモリの特定のエリアにセーブする部分について説明をしました。
その続きです。
0166 31D1FF LXI SP,MONSP
0169 3AF2FF LDA BRKCT
016C A7 ANA A
016D CA8B01 JZ BSTOP
0170 2AF0FF LHLD BRKAD
0173 EB XCHG
0174 2AE0FF LHLD PSAVE
0177 7D MOV A,L
0178 BB CMP E
0179 C28501 JNZ NOBRK
017C 7C MOV A,H
017D BA CMP D
017E C28501 JNZ NOBRK
0181 21F2FF LXI H,BRKCT
0184 35 DCR M
0185 CD9101 NOBRK:CALL ADDSP
0188 C3F901 JMP RESRG
018B CD9101 BSTOP:CALL ADDSP
018E C35100 JMP START
0191 2AEAFF ADDSP:LHLD FSAVE
0194 22ECFF SHLD DATA
0197 2AE0FF LHLD PSAVE
019A 22EEFF SHLD ADRES
019D CDA101 CALL RGDSP
01A0 C9 RET
前回は、レジスタをメモリに保存する方法として、スタックポインタを利用するテクニックが使われていることを説明しました。
モニタプログラムもいろいろな命令を実行するなかでスタックを使いますから、レジスタのセーブが済んだら、まずスタックを設定しなければなりません。
モニタプログラムはユーザープログラムとは別の働きをしますから、モニタプログラム専用のスタック領域を割り当てます。
それがMONSP(FFD1)です。
LXI SP命令でFFD1をスタックポインタに書き込みます。
こうすることで、モニタプログラムのスタック領域がFFD0から前の部分に割り当てられます。
さて次の
LDA BRKCT
ANA A
JZ BSTOP
ですが、これがさきほど少し説明した、「ブレイク」動作に対応している部分です。
TK80はワンステップ動作と同じ仕組みを利用して、ブレイク動作というものを利用することができます。
ワンステップ動作は、最初から1命令ずつ実行していきますが、ブレイク動作は、あるプログラムアドレスまではワンステップにしないで続けて実行し、指定したアドレスまできたら、ブレイクして、そこからはワンステップ動作になる、というものです。
さらに指定アドレスの命令を何回か実行したあとでブレイクする、というような指定もすることができます。
その場合には、このBRKCT(多分Break Counterの意。アドレスFFF2)に繰り返し回数を指定します。
ワンステップ動作の場合には、繰り返し回数には00を指定します(リセット後の初期状態では00になっています)。
BRKCTの値が00ならばBSTOPへJMPします。
ワンステップ動作の場合には00ですから、必ずBSTOPに行くことになります。
ですから、その下の0170から018Aまでのところは、関係がないことになります。
ここは、ブレイク動作のための部分です。
でも、ついでですから、ほんの少しだけ、簡単に説明しますと、ブレイク動作では、ブレイク回数とともに、ブレイクさせるアドレスも指定します。
BRKAD(FFF0、FFF1)にアドレスを書き込んでおきます。
0170から018Aまでの部分で、その指定したアドレスと、この割込みプログラムの始めのところで、メモリにセーブしたプログラムカウンタとの比較を行います。
一致しないときは、そのままLED表示ルーチンをCALLしてから、ユーザプログラムの実行へもどります(RESRGルーチンへ行く)。
一致したときは、ブレイクカウンタの値を−1してから、LED表示ルーチンをCALLして、ユーザープログラムの実行へ戻ります。
ステップ動作の場合には、やはり同じようにLED表示ルーチン(ADDSP)をCALLしたあと、モニタプログラムのエントリルーチンに行きます。
ADDSPはLEDにアドレスとデータを表示するルーチンです。
LEDにデータを表示する仕組みについては、また別のところで説明をするつもりですが、少しだけ、簡単に説明しておきます。
LEDに表示するためには、データ表示部(LEDの右4桁)に表示する値は、DATA(FFEC、FFED)に書き込み、またアドレス表示部(LEDの左4桁)に表示する値は、ADRES(FFEE、FFEF)に書き込みます。
そのあと、RGDSPをCALLすると、ADRES、DATAの値がLEDに表示されます。
RGDSPは、FFEC〜FFEFの値を、最終的にLEDに表示するための表示バッファFFF4〜FFF7に転送し、そこからさらにセグメントデータに変換して、LEDのDMA表示アドレスである、FFF8〜FFFFにセグメントデータを書き込みます。
さて、ステップ動作のその後なのですが、ADDSPルーチンによって、プログラムカウンタの値をLEDのアドレス表示部(左4桁)に表示するとともに、Aレジスタの値とフラグレジスタの値を、LEDのデータ表示部(右4桁)に表示したあと、モニタプログラムのエントリルーチンに行ってしまいます。
BSTOP:CALL ADDSP
JMP START
ADDSP:LHLD FSAVE
SHLD DATA
LHLD PSAVE
SHLD ADRES
CALL RGDSP
RET
がその部分です。
FSAVE(FFEA、FFEB)はフラグとAレジスタをセーブしたメモリアドレスで、PSAVE(FFE0、FFE1)はプログラムカウンタをセーブしたメモリアドレスです。
このあと、モニタのエントリルーチンに行ってから、いったいぜんたいステップ動作はどのように処理されるのでしょうか。
その説明は、また次回へと続きます。
2009.6.15upload
前へ
次へ
ホームページトップへ戻る