MICROSの制作

 

I.目的

2つのユーザプログラムがマルチプログラム方式で走るOSを作る。TSSのようなタイムスライスは行わず、あるプロセスがキーボード入力でWAIT状態になった時、他のREADY状態のプロセスが走る。

 

今回は、さらに単純化し(次に示す)2つのユーザプログラムが走ればよい。

(1)   ユーザプログラム1:一文字読んでは1文字書き出すことを繰り返すフォアグラウンプログラム

USRPR1              READ    U1DA,U1LEN

                            OUT      U1DA,U1LEN

                            JUMP    USRPR1

U1DA                  DS         1

U1LEN                DS         1

 

(2)ユーザプログラム2:LD,STを繰り返すバックグラウンドプログラム

USRPR2              LD         GR4,U2DC1

ST          GR4,U2DA

                            JUMP    USRPR2

U2DC1                DC         1

U2DA                  DS         1

(注:バックグラウンドは、フォアグラウンドが入力待ちの間だけ走る。)

(注:状態判定がないため、プロセス切換えに伴うフラグレジスタの退避が不要)

 

II.使用ソフトウエア

CASL2をマルチプログラミング用に改造したものCASL2xを使用。

改造点は次の2点

(1)  IN命令の処理をスレッド化しメインのスレッドと並行して動作するようにした。

 

(2)次の4つの命令を追加する

(a)READ  :ユーザが使える入力命令

第1オペランド:入力領域、第2オペランド:入力文字数が入る番地

(注:この命令の中で、SVC(superviser Call)SCINを発生)

(b)LPSW(Load PSW):メモリに格納されている番地へ飛ぶ(OSのみ使用可)

 オペランド:ジャンプ先の入っているアドレス

(c)IDLE:ユーザモードになりひたすらIDLEを繰り返す(OSのみ使用可)

(どんな時に使うか:RUNプロセスがない時、IO割り込みを待つ時)

(d)SIO (StartIO)IOデバイスに動作開始を指示。

(ユーザがREAD命令で入力を指示すると、GR6に入力データを格納する番地、GR7に入力文字数を入れる番地、を格納してSystem Callの割込み(割出し)を起こす。この割出しで制御がOSに移ると、その中でSIO命令を出しIOを開始させる。)

 

(3)MICROS開発ツール

CPUEMディレクトリのinthディレクトリのmainを使用。

 

III. MICROSのための記憶領域割当て

(1)汎用レジスタの割当て

OS用:GR0,GR1,GR2,GR3;

ユーザ用:GR4,GR5;

標準入出力用:GR6,GR7;GR6,7を入出力専用に使う。使用禁止)

 

(2)Main Memoryの割当て

 

アドレス

名前

機能

説明

0

OPSW

Old PSW

割込み発生時にPRが自動保存

1

IOINT

入出力割込み

1文字入力完了時に1が立つ

2

IOSTS

標準入出力装置の状態

IOデバイス使用中は1

3

SCINT

SystemCall割出し

SCIN1を書く

4

IOISA

割込み処理ルーチン開始番地

IOINT1の時の飛び先番地

5

SCINSA

SystemCall処理開始番地

SCINT1の時の飛び先番地

6

 

 

 

7

 

 

 

8

RUN

実行中のプロセス

Process番号(1又は2

9

READY

実行可能プロセス

Process番号(今回は2or0

10

WAIT

IO待ちプロセス

Process番号(今回は1or0

11

MOD

OSモードかUserモードか

OSモード(1)は割込み禁止

12

 

 

 

13

P1AS

Process1PR退避所

 

14

P1GR4

Prosess1GR4退避所

 

15

P1GR5

Prosess1GR5退避所

 

16

 

 

 

17

P2SA

Process2PR退避所

 

18

P2GR4

Prosess2GR4退避所

 

19

P2GR5

Prosess2GR5退避所

 

20

 

 

 

 

専用エリア

(特殊レジスタ:0〜3番地はハードウエアがセット、4番地以降はOSがセット)

0番地は割込み発生時のPCを保存する場所(いわゆる旧PSWPR部)

1番地は割込レジスタ。(IO割込みが発生すると1が立つ)

2番地はIO状態レジスタ。(IOが使用中か否かを示す。Busy=1

3番地は(READ命令の中で)System Call命令(CASL2SVC命令SCIN)が1を立てる

4番地はIO割込処理ルーチンの開始番地(IO割込み用、新PSW)

5番地はSCIN処理ルーチンの開始番地(SCIN用、新PSW)

 

8番地は実行中(RUN)のプロセス番号が入る

9番地は実行可能状態(READY)のプロセス番号が入る

10番地はIO終了待ち(WAIT)のプロセス番号が入る

11番地はOSが走る時1になり、この時は割込み禁止。(CPUエミュレータ内でのみ使用)

 

13〜15番地はユーザプログラム1(プロセス1)用、退避領域

13番地はユーザプログラム開始番地。PR(Program Counterとも呼ばれる)が退避される

14番地はGR4退避領域

15番地はGR5退避領域

 

17〜19番地はユーザプログラム2(プロセス2)用、退避領域

17番地はユーザプログラム開始番地。PRが退避される。

18番地はGR4退避領域

19番地はGR5退避領域

 

 

IV. 割込み処理(COMET2に追加した機能)

実行モード(11番地)がユーザモード”0”の場合は、命令ファッチ直前にIOINT(1番地)とSCINT(3番地)を調べ、割込みが有ったらPRPR:program counter)を0番地に退避し、割込みの種類に応じて新PSW(割込み処理ルーチンの開始番地)をPRにセットする。要するに、IO割込みならIOISASCIOならSCISAに格納されている番地へ飛ばしす。

(備忘1:割込みが有ったら、すぐOSモードにし、LPSWUSERモードに戻す)

(備忘2:各割込み処理ルーチンでは先ず、退避されているPSWを各プロセス用退避領域に保存すること)

IO割込み:IO装置は入出力処理を終わると1番地に1を書き込む。

READ命令は中で、System Call により3番地に1を書き込む

 

V. MICROSの動き

 

MICROSはプロンプト(>)を表示してコマンドを待つ

コマンドは2種類

F:ユーザプログラム1(フォアグラウンド)のみを実行

B:ユーザプログラム2(バックグラウンド)のみを実行

A:両ユーザプログラム(フォアグラウンドとバックグラウンド)を並列実行

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

VI.プログラムの型紙

MICROS             START   INIT

;ハードウエアレジスタエリア

OPSW   DS         1;OldPSW

IOINT   DS         1;IO割り込みは1

IOSTS   DS         1;IO状態、0ならREADY、1ならBUSY

SCINT   DS         1;SystemCall割出し、SCINは1をセット

IOISA    DS         1;割込み処理開始番地

SCINSA              DS         1;SystenCallIN割出し処理開始番地

RSV1     DS         2;未使用

;OSエリア

RUN      DS         1;実行中のプロセス

READY DS         1;実行可能プロセス

WAIT     DS         1;IO終了待ちプロセス

MOD     DS         1;OSmode=1,UserMode=0;

RSV2     DS         1;未使用

;ユーザプロセス1用退避エリア

P1SA     DS         1;再開アドレス

P1GR4   DS         1;GR4退避

P1GR5   DS         1;GR5退避

RSV3     DS         1;未使用

;ユーザプロセス2用退避エリア

P2SA     DS         1;再開アドレス

P2GR4   DS         1;GR4退避

P2GR5   DS         1;GR5退避

RSV4     DS         1;未使用

;OS変数、定数

PPT       DC         '>'

DC0       DC         0

DC1       DC         1

DC2       DC         2

DC4       DC         4

DC19     DC         19

CMD      DS         1

ILEN     DS         1

FG         DC         'F'

FB         DC         'B'

FA          DC         'A'

PG1       DC         1

PG2       DC         2

 

;初期設定

;019番地を0クリアし、割込みベクトル等をセット

   :

;コマンド処理

;>プロンプトを出して指示を待つ。

;fならPR1だけを走らせ(RUNPR1を入れ、READY,WAITを空にしてPMAN)

;bならPR1PR2を同時に走らす(RUNPR1,READYPR2,WAITを空にしてPMAN)

 

CMDP   OUT      PPT,DC1;プロンプト表示

             

FGD      LD         GR0,PG1

    :

              JUMP    PMAN

BGD      LD         GR0,PG2

             

              JUMP    PMAN

ALL       LD         GR0,PG1

          

              JUMP    PMAN

 

;PMANプロセス管理

;RUNPG1が入っていればPR1を走らせ、PR2が入っていればPR2を走らす。

PMAN   LD         GR0,DC1

          

STAPG1              LD         GR4,P1GR4

              LPSW    P1SA

STAPG2              LD         GR4,P2GR4

              LPSW    P2SA

IDL        IDLE

 

;IO割り込み

;PSWOPSWに退避されてここに来るので、OPSWGR4,5PG2領域に退避し、

;(割り込まれるのはPR2)、RUN(PR2)READYに入れ、

;WAIT(PG1)RUNに入れ、WAITを空にし、PMAN(プロセス管理)へ

IOI        LD         GR0,DC0;RUNプロセス無いならIDLW

             

              JUMP    PMAN

 

;SystemCallIN(SCIN)

;PSWOPSWに退避されてここにくるので、OPSWPG1領域に退避し

;(これを出すのは今回PR1のみ)、READY(PG2)RUNに入れ、READYを空にし、

;WAITPG1を入れ、SIOを出してINスレッドを走らせ、PMAN(プロセス管理へ)

SCIN     LD         GR0,OPSW

              SIO

              JUMP    PMAN

 

;ユーザプログラム1:一文字読んでは1文字書き出すことを繰り返す

USRPR1              OUT      PAS3,DC4

              READ    U1DA,U1LEN

              OUT      U1DA,U1LEN

              JUMP    USRPR1                           

U1INC   DC         'INPUT'

U1LEN  DS         1

U1DA    DS         3

 

;ユーザプログラム2:LD,STを繰り返す

USRPR2              LD         GR4,U2DC1

              ST          GR4,U2DA

              JUMP    USRPR2

U2DC1  DC         1

U2DA    DS         1

              END

 

付録(MICROSのためのエミュレータ修正備忘録、古谷用)

(1)  READ:第一オペランドをGR6、第二オペランドをGR7に入れてSVC6を出す。

SVC6では、3番地(SCINT)に1を立てる。

(入力はINスレッドで実行される)

(2)  WAIT:2番地が0でない時WAIT命令を繰り返し実行。

(3)  LPSWは間接JUMPとして実現。

(4)  命令フェッチ前の割込み処理は、

1番地と3番地をチェックし、OSモードにする。

(5)  IDLE処理:PMANRUNに何もない時、IDLEを呼ぶ。IO割込みでは、まずRUNプロセスが有るかを調べ、有れば状態退避、無ければ退避せず。

(6)  IN,OUTCASL2本来のIO

(7)  INX,OUTXIOのスレッド実行。スレッドではGR6を入力データの格納場所、GR7を入力文字数の格納場所に使用。

(8)  INスレッド内でIOSTSを1にしていたが、INXの場合INXの前でIOSTSに1を入れ、INXの後でWAITを出さないと入力を待たずに抜けちゃう。