テストプログラムについて
情報科学実験Cで学生が設計したCPUをテストするためのサンプルプログラムがROMに格納されている。SEP-3の命令セット(学生が独自に追加した命令は除く)の動作確認のために使用する。サンプルプログラムは5つ用意されており、命令の動作を確認することができる。なお、テストの前提としてmov命令や入出力の回路は「正しく動作する」ことを仮定している。演算結果の正確さを確認するだけでなく、演算の結果、設定されるPSWのフラグが正しくセットされているかどうかを含めてチェックすること。SUB系のCフラグのセット/リセットについて特に重点的に点検すること。
サンプルプログラムは、以下のとおりである。
- サンプルプログラム1
シフト命令(ASL, ASR, LSL, LSR, ROL, ROR)とクリア命令(CLR)のテスト - サンプルプログラム2
論理演算命令(OR, XOR, AND)のテスト - サンプルプログラム3
算術演算命令(ADD, SUB),及びBRx命令のテスト - サンプルプログラム4
分岐命令(JMP, RJP, RBx)のテスト - サンプルプログラム5
サブルーチンコール命令(JSR, RJS, RET)のテスト
サンプルプログラム実行方法
各サンプルプログラムは、0xf800番地の「実行開始番地入力ルーチン」で各サンプルプログラムの開始番地を入力し、開始番地へジャンプすることで実行することができる。
各サンプルプログラム個々の実行内容は後にそれぞれ記す通りである。
「実行開始番地入力ルーチン」の実行方法はサービスルーチンのページを参照のこと。
各サンプルプログラムの開始番地は以下の表1の通りである。
サンプルプログラム名 | 開始番地 | 主にテストする命令 |
---|---|---|
サンプルプログラム1 | 0xf840 | ASL, ASR, LSL, LSR, ROL, ROR, CLR |
サンプルプログラム2 | 0xf848 | OR, XOR, AND |
サンプルプログラム3 | 0xf850 | ADD, SUB, BRx |
サンプルプログラム4 | 0xf858 | JMP, RJP, RBx |
サンプルプログラム5 | 0xf860 | JSR, RJS, RET |
サンプルプログラム1(0xf840〜)
サンプルプログラム1では、CLR命令及びシフト命令(ASL, ASR, LSL, LSR, ROL, ROR)のテストを行う。16bit赤色LED(以下、データ出力LED)を使用して、データがシフトされていく様子を観察できるプログラムである。シフトするデータは4種類のシフト命令の特徴を観測できるようなデータをセットしてある。0xf840番地からスタートすると以下の順でテストが行われる。
第1チェック CLR命令
- データ出力LEDに0xFFFFが表示される。(0xffffが表示されない場合、JMP命令のミスかも)
- ACK待ち
- データ出力LEDがすべて消える(0x0000が表示される)
データ出力ランプがすべて消えれば、CLR命令は正しく動作されている。
第2チェック ASL命令
- データ出力LEDに0x7A80が表示される。
- ACK待ち
- 算術左シフトを実行、結果をデータ出力LEDに表示する
- キャリーが発生していれば、2.へ戻る
7A80→7500→6A00→5400→2800と変化することが確認できれば、ASL命令は正しく動作していると考えられる。
第3チェック ASR命令
- データ出力LEDに0x80A8が表示される。
- ACK待ち
- 算術右シフトを実行、結果をデータ出力LEDに表示する
- キャリーが発生していなければ、 2.へ戻る
80A8→C054→E02A→F015と変化することが確認できれば、ASR命令は正しく動作していると考えられる。
第4チェック LSL命令
- データ出力LEDに0xF500が表示される。
- ACK待ち +論理左シフトを実行、結果をデータ出力LEDに表示する
- キャリーが発生していれば、2.へ戻る
F500→EA00→D400→A800→5000と変化することが確認できれば、LSL命令は正しく動作していると考えられる。
第5チェック LSR命令
- データ出力LEDに0x0A0Fが表示される。
- ACK待ち
- 論理右シフトを実行、結果をデータ出力LEDに表示する
- キャリーが発生していれば、2.へ戻る
0A0F→0507→0283→0141→00A0と変化することが確認できれば、LSR命令は正しく動作していると考えられる。
第6チェック ROL命令
- データ出力LEDに0xF0A0が表示される。
- ACK待ち
- ローテート左シフトを実行、結果をデータ出力LEDに表示する
- キャリーが発生していれば、2.へ戻る
F0A0→E141→C283→8507→0A0Fと変化することが確認できれば、ROL命令は正しく動作していると考えられる。
第7チェック ROR命令
- データ出力LEDに0x0A0Fが表示される。
- ACK待ち
- ローテート右シフトを実行、結果をデータ出力LEDに表示する
- キャリーが発生していれば、2.へ戻る
0A0F→8507→C283→E141→F0A0と変化することが確認できれば、ROR命令は正しく動作していると考えられる。
サンプルプログラム1は最後にHALT命令によって停止する。
以下にサンプルプログラム1のアセンブリコードを示す。
.=0xf840 jmp label_0xf9b0 .=0xf9b0 label_0xf9b0: mov #0xffe0,r0 mov #0xffff,r1 mov r1,(r0) mov (r0),r2 clr r1 mov r1,(r0) mov (r0),r2 mov #0x7a80,r1 label_0xf9bb: mov r1,(r0) mov (r0),r2 asl r1 rbc label_0xf9bb mov #0x80a8,r1 label_0xf9c2: mov r1,(r0) mov (r0),r2 asr r1 rbc label_0xf9c9 rjp label_0xf9c2 label_0xf9c9: mov #0xf500,r1 label_0xf9cb: mov r1,(r0) mov (r0),r2 lsl r1 rbc label_0xf9cb mov #0x0a0f,r1 label_0xf9d2: mov r1,(r0) mov (r0),r2 lsr r1 rbc label_0xf9d2 mov #0xf0a0,r1 label_0xf9d9: mov r1,(r0) mov (r0),r2 rol r1 rbc label_0xf9d9 mov #0x0a0f,r1 label_0xf9e0: mov r1,(r0) mov (r0),r2 ror r1 rbc label_0xf9e0 hlt
サンプルプログラム2(0xf848〜)
サンプルプログラム2では、論理演算命令(OR, XOR, AND)のテストを行う。データ出力LEDを使用して、各論理演算の1ビット毎の演算結果を確認する。データ出力LEDの下位4ビットの変化は表2の通りである。
演算の意味実行順 | 入力LEDR[3] | 入力LEDR[2] | 入力LEDR[1] | 入力LEDR[0] | 結果LEDR[3..0] |
---|---|---|---|---|---|
(1)OR | 1 or 1 | 1 or 0 | 0 or 1 | 0 or 0 | 1110 |
(2)XOR | 1 xor 1 | 1 xor 0 | 0 xor 1 | 0 xor 0 | 0110 |
(3)AND | 1 and 1 | 1 and 0 | 0 and 1 | 0 and 0 | 1000 |
データ出力LEDの下位4ビットが1110→0110→1000と変化することが確認できれば、論理演算命令は正しく動作していると考えられる。
以下にサンプルプログラム2のアセンブリコードを示す。
.=0xf848 jmp label_0xf9f0 .=0xf9f0 label_0xf9f0: mov #0xffe0,r0 mov #0x000c,r1 mov #0x000a,r2 or r2,r1 mov r1,(r0) mov (r0),(r0) mov #0x000c,r1 xor r2,r1 mov r1,(r0) mov (r0),(r0) mov #0x000c,r1 and r2,r1 mov r1,(r0) mov (r0),(r0) hlt
サンプルプログラム3(0xf850〜)
サンプルプログラム3では、算術演算命令(ADD,SUB)及びPSW(N,Z,V,C)のセットと分岐命令(BRx)のテストを行う。テスト対象の分岐命令をすべて正しく実行するとデータ出力LEDに0x0001が表示されて、HALT命令により停止する。
第1チェック ADD命令
- 0xEFFF+1 を実行する
- データ出力LEDに0xF000が表示される。
- ACK待ち
データ出力ランプにF000が表示されれば、ADD命令は正しく動作していると思われる。
第2チェック SUB命令
- 0xF000−0xF000 を実行する
- データ出力LEDがすべて消える(0x0000が表示される)。
- ACK待ち
データ出力ランプがすべて消灯していれば、ADD命令は正しく動作していると思われる。
第3チェック BRx命令
- PSWの各フラグを立てる
- フラグにしたがって条件判定ジャンプを行う
- 終了コード0x0001をデータ出力LEDに出力して停止する。
データ出力LEDに0x0001が表示されれば、PSWの各フラグのセットとBRx命令は正しく動作しているものと思われる。
以下にサンプルプログラム3のアセンブリコードを示す。
.=0xf850 jmp label_0xfa10 .=0xfa10 label_0xfa10: mov #0xffe0,r0 mov #0x0001,r1 mov #0xefff,r2 add r1,r2 mov r2,(r0) mov (r0),(r0) sub r2,r2 mov r2,(r0) mov (r0),(r0) mov #0x0008,r5 brn label_0xfa21 hlt label_0xfa21: mov #0x0004,r5 brz label_0xfa26 hlt label_0xfa26: mov #0x0002,r5 brv label_0xfa2b hlt label_0xfa2b: mov #0x0001,r5 brc label_0xfa30 hlt label_0xfa30: mov r1,(r0) hlt
サンプルプログラム4(0xf858〜)
サンプルプログラム4では、PSW(N,Z,V,C)のセットと分岐命令(JMP, RJP, RBx)のテストを行う。テスト対象の分岐命令をすべて正しく実行するとデータ出力LEDに0x0001を表示して停止する。他のサンプルプログラムでは、PSWの評価とそれに伴う分岐を使用しているため、このプログラムによるチェックを最初にテストするとよい。
チェック 分岐命令
- プログラム開始
- 条件分岐命令の場合には、対応するPSWのフラグをたてる
- 分岐命令を実行する
すべて正しく分岐すればデータ出力LEDに0x0001を出力して停止する。フラグの判定が正しく行われていないと、データ出力LEDに0xFFFFを出力して停止する(はず)。
データ出力LEDに0x0001が表示されれば、PSWの各フラグのセットと分岐命令(JMP,RJP,RBx)は正しく動作しているものと思われる。
以下にサンプルプログラム4のアセンブリコードを示す。
.=0xf858 jmp label_0xfa40 label_0xfa40: mov #0xffe0,r0 jmp label_0xfa47 mov #0xffff,(r0) hlt label_0xfa47: rjp label_0xfa4b jmp label_0xfa66 label_0xfa4b: mov #0x0008,r5 rbn label_0xfa51 jmp label_0xfa66 label_0xfa51: mov #0x0004,r5 rbz label_0xfa57 jmp label_0xfa66 label_0xfa57: mov #0x0002,r5 rbv label_0xfa5d jmp label_0xfa66 label_0xfa5d: mov #0x0001,r5 rbc label_0xfa63 jmp label_0xfa66 label_0xfa63: mov #0x0001,(r0) hlt label_0xfa66: mov #0xffff,(r0) hlt
サンプルプログラム5(0xf860〜)
サンプルプログラム5では、サブルーチンコール命令(JSR, RJS, RET)のテストを行う。データ出力LEDに0x0001→0x0002の表示されて停止すれば、正しくサブルーチンへジャンプして戻って来ていることを確認できる。正しく分岐しない、正しく復帰しないときには、どこへ分岐するか予測不能なためPCの値などを参考にして下位の修正を行う。プログラムの流れは以下のとおり。
第1チェック JSR命令
- JSR命令を実行
- データ出力LEDに0x0001を表示
- ACK待ち +RET命令を実行
データ出力LEDに0x0001が表示されていれば、JSR命令は正しく動作している。
第2チェック RJS命令
- RJS命令を実行
- データ出力LEDに0x0002が表示される。
- ACK待ち
- RET命令を実行
- HLT命令で停止。
データ出力LEDに0x0002が表示されていれば、サブルーチンコール命令(JSR,RJS,RET)は正しく動作している。
以下にサンプルプログラム5のアセンブリコードを示す。
.=0xf860 jmp label_0xfa70 .=0xfa70 label_0xfa70: mov #0xffe0,r0 mov #0x0001,r1 jsr label_0xfa7b mov (r0),r2 add r1,r1 rjs label_0xfa7b hlt label_0xfa7b: mov r1,(r0) ret