simh を読んでみる

Lions' 本でハマッている割り込み、トラップからの復帰時のスタックの状態を確認すべく、simh のソースを読んでみることに。
とゆーのも昨晩の Lions' 呑み会またの名を geektable にて mgwave すずきさんから挙動が分からない時はシミュレータのソースを読めばよろしい、という非常にアレゲな助言を頂戴したことによります。正にすばら。

つーことで

とりあえずバイナリパケジを入れてなかったので導入し、

$ sudo apt-get install simh
$ dpkg -L sihm
/.
/usr
/usr/bin
/usr/bin/pdp1
/usr/bin/pdp4
/usr/bin/pdp7
/usr/bin/pdp8
/usr/bin/pdp9
/usr/bin/pdp15
/usr/bin/pdp11
/usr/bin/pdp10
/usr/bin/vax
/usr/bin/vax780
/usr/bin/dgnova
/usr/bin/eclipseemu
/usr/bin/h316
/usr/bin/hp2100
/usr/bin/gri909
/usr/bin/i1401
/usr/bin/i1620
/usr/bin/system3
/usr/bin/altair
/usr/bin/altairz80
/usr/bin/id16
/usr/bin/id32
/usr/bin/sds
/usr/bin/lgp
/usr/bin/i7094
/usr/bin/dtos8cvt
/usr/bin/gt7cvt
/usr/bin/macro1
/usr/bin/macro7
/usr/bin/macro8x
/usr/bin/mtcvtv23
/usr/bin/mtdump
/usr/bin/littcvt
/usr/bin/mtcvtodd
/usr/bin/sfmtcvt
/usr/bin/config11
/usr/bin/sdsdump
/usr/bin/mtcvtfix
/usr/bin/mmdir
/usr/bin/tp512cvt
/usr/share
/usr/share/doc
/usr/share/doc/simh
(以下略
$

おもむろに別端末でソース入手。

$ apt-get source simh

あら、さきほどもそうだったんですが、dpkg-dev パケジが導入されていない模様。入れておきましょうね。
で、qemu-system も再度ソース入手してみます (別途確認)。

確認着手

そのまえに gtags -v して中身掘削着手。ファイル名から機能の類推ができん。とりあえず trap で find|xargs grep してみたら pdp11_cpu.c あたりに _Check for traps or interrupts._ みたいなコメントを見つけたので中身を確認。以下な記述がありました。

/* Process a trap or interrupt

   1. Exit wait state
   2. Save the current SP and PSW
   3. Read the new PC, new PSW from trapea, kernel data space
   4. Get the mode and stack selected by the new PSW
   5. Push the old PC and PSW on the new stack
   6. Update SP, PSW, and PC
   7. If not stack overflow, check for stack overflow
*/

問題になってるのは戻りなんだけどなぁ。rtt 命令か。以下らしい。

            case 6:                                     /* RTT */
                if (!CPUT (HAS_RTT)) {
                    setTRAP (TRAP_ILL);
                    break;
                    }
            case 2:                                     /* RTI */
                src = ReadW (SP | dsenable);
                src2 = ReadW (((SP + 2) & 0177777) | dsenable);
                STACKFILE[cm] = SP = (SP + 4) & 0177777;
                oldrs = rs;
                put_PSW (src2, (cm != MD_KER));         /* store PSW, prot */
                if (rs != oldrs) {
                    for (i = 0; i < 6; i++) {
                        REGFILE[i][oldrs] = R[i];
                        R[i] = REGFILE[i][rs];
                        }
                    }
                SP = STACKFILE[cm];
                isenable = calc_is (cm);
                dsenable = calc_ds (cm);
                trap_req = calc_ints (ipl, trap_req);
                JMP_PC (src);
                if (CPUT (HAS_RTT) && tbit &&           /* RTT impl? */
                    (IR == 000002)) setTRAP (TRAP_TRC); /* RTI immed trap */
                break;

ソースは pdp11_cpu.c です。現時点でのざっくり見た印象ですと psig 手続きの謎はとけそうにないカンジ。これからメシ炊きらしいので、別途確認して追記の方向ッス。