home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 308_01 / msu.c < prev    next >
C/C++ Source or Header  |  1990-06-17  |  37KB  |  1,378 lines

  1.  
  2.  
  3. /* The following are the various constants defined and
  4.  * used in the simulation software for the MSU1 machine. 
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9.  
  10. #define TRUE  1  /* boolean to represent the true 
  11.                     value */
  12. #define FALSE 0  /* boolean to represent the false
  13.                     value */
  14. #define READ  1  /* this is defined constant for the 
  15.                     read operation */
  16. #define WRITE 0  /* this is defined constant for the
  17.                     write operation */ 
  18. #define maxsize  4096  /* main memory size declared
  19.                           as a constant */ 
  20. #define maxint   2147483674  /* the maximum integer for 
  21.                                 32 bits computer */
  22. #define file1 "msu.dat" /* define the input
  23.                                          file name */
  24. #define file2 "msu.out"  /* define the output
  25.                                          file name */
  26.  
  27.  
  28.  
  29.  
  30. /* The following global variables are used and defined
  31.  * in the MSU1 software program.
  32.  */
  33.  
  34. int rwsignal,    /* read action set to 1,
  35.                     write action set to 0 */
  36.     L0, base0,   /* the length & base address of 
  37.                     the program */
  38.     L1, base1,   /* the length & base address of the
  39.                     input buffer */
  40.     L2, base2,   /* the length & base address of the
  41.                     output buffer */
  42.     L3, base3,   /* the length & base address of the
  43.                      workspace */
  44.     jobid = 0,   /* for the job identification */
  45.     clock, trace,  /* for variables clock, trace */
  46.     FLAG = 1;      /* flag signal use boolean express */
  47.  
  48. FILE *in, *out;    /* input, output file pointers */
  49. unsigned CHANNEL,       /* read or write address */
  50.          MEM[maxsize];  /* declares the memory space */    
  51. char c,             /* character read from input file */
  52.      *mne,          /* stands for instruction name */
  53.      *maskmode;     /* mask value from 0000 to 1111 */
  54.  
  55.  
  56.  
  57.  
  58. /* The GI instruction format:
  59.  *
  60.  *  +--------+------+----------+------+----------+
  61.  *  | opcode |  S1  |    D1    |  S2  |    D2    |
  62.  *  +--------+------+----------+------+----------+
  63.  *   31    26 25  24 23      13 12  11 10       0
  64.  */
  65.  
  66.  
  67. typedef struct instruction_tag1
  68. {
  69.   unsigned d2 : 11; /* displacement value of the 
  70.                        operand2 */
  71.   unsigned s2 :  2; /* origin register of the operand2 */
  72.   unsigned d1 : 11; /* displacement value of the
  73.                        operand1 */
  74.   unsigned s1 :  2; /* origin register of the operand1 */
  75.   unsigned op :  6; /* opcode */
  76. };
  77.  
  78.  
  79.  
  80.  
  81. /* The BI instruction format:
  82.  *
  83.  *  +--------+------+----------+------+----------+
  84.  *  | opcode |  M   | not used |  S1  |    D1    |
  85.  *  +--------+------+----------+------+----------+
  86.  *   31    26 25  22 21      13 12  11 10       0
  87.  */
  88.  
  89.  
  90. typedef struct instruction_tag2
  91. {
  92.   unsigned d1   : 11; /* displacement value of the
  93.                          operand1 */
  94.   unsigned s1   :  2; /* origin register of the 
  95.                          operand1 */
  96.   unsigned nu   :  9; /* not used */
  97.   unsigned mask :  4; /* mask bits used in branching
  98.                          instruction */
  99.   unsigned op   :  6; /* opcode */
  100. };
  101.  
  102.  
  103.  
  104.  
  105. /* The PSW format:
  106.  *
  107.  *  +------+------+------------------------------+
  108.  *  |  CC  |  IC  |     program counter (PC)     |
  109.  *  +------+------+------------------------------+
  110.  *   31  28 27  24 23                           0
  111.  */
  112.  
  113.  
  114. typedef struct psw_tag
  115. {
  116.   unsigned pc : 24;     /* program counter */
  117.   unsigned ic :  4;     /* interrupt code */
  118.   unsigned cc :  4;     /* condition code */     
  119.  };
  120.  
  121.  
  122.  
  123.  
  124. /* The segment origin register format:
  125.  * 
  126.  *  +-------------------+------------------------+
  127.  *  |    base address   |   length of segment    |
  128.  *  +-------------------+------------------------+
  129.  *   31               18 17                     0
  130.  */
  131.  
  132.  
  133. typedef struct reg
  134. {
  135.   unsigned length : 18;     /* length of segment */
  136.   unsigned base   : 14;     /* base address */
  137. };
  138.  
  139.  
  140.  
  141.  
  142. union
  143. {
  144.   struct psw_tag index;
  145.   unsigned value;
  146. } PSW;     /* Processor Status Word */
  147.  
  148.  
  149.  
  150. union
  151. {
  152.   struct instruction_tag1 gi;
  153.   struct instruction_tag2 bi;
  154.   unsigned value;
  155. } IR;      /* Instruction Register */
  156.  
  157.  
  158.  
  159.  
  160. union
  161. {
  162.   struct reg seg;
  163.   unsigned value;
  164. } ciow[4];    /* code, input, output, workspace */
  165.  
  166.  
  167.  
  168.  
  169. /*=====================================================*
  170.  *                       main                          *
  171.  *=====================================================*/
  172. main()
  173. {
  174.   /* The main function call the other functions to 
  175.    * open the input/output file. Also, when the _SYSTEM
  176.    * return his job and return to main, the main 
  177.    * functin will call file_close() to close all the
  178.    * files which it has been open.
  179.    */
  180.  
  181.   read_input_file();       /* open an input file   */
  182.   write_output_file();     /* open an output file  */
  183.   _SYSTEM();
  184.   file_close();
  185. }
  186.  
  187.  
  188.  
  189.  
  190. /*====================================================*
  191.  *                read_input_file                     *
  192.  *====================================================*/
  193. read_input_file()
  194. {
  195.   /* This function opens an input file. */
  196.  
  197.   extern FILE *in;
  198.   extern char c;
  199.   void _error();
  200.  
  201.   if ((in = fopen(file1,"r")) == NULL) {
  202.      _error(1);
  203.      exit(3);
  204.   }
  205.   else {
  206.          c = getc(in);
  207.          /* skip the space and end of line */
  208.          while (isspace(c) || (c == '\n'))  
  209.                c = getc(in);
  210.          if (c == EOF) {
  211.             _error(2);
  212.             exit(4);
  213.          }
  214.   }
  215. }
  216.  
  217.  
  218.  
  219.  
  220. /*====================================================*
  221.  *                write_output_file                   *
  222.  *====================================================*/
  223. write_output_file()
  224. {
  225.   /* This function opens a output file. */
  226.  
  227.   extern FILE *out;
  228.   void _error();
  229.  
  230.   /* if can not open */
  231.   if ((out = fopen(file2,"w")) == NULL) { 
  232.      _error(3);
  233.      exit(5);
  234.   }
  235. }
  236.  
  237.  
  238.  
  239.  
  240. /*====================================================*
  241.  *                     _SYSTEM                        *
  242.  *====================================================*/
  243. _SYSTEM()
  244. {
  245.   /* The _SYSTEM function act as the main driver in
  246.    * MSU1 machine. The modules LOADER, MEMORY, CPU and
  247.    * INTERRUPT are called from this function. This loops
  248.    * repeats until all the jobs are finished.
  249.    */
  250.  
  251.   extern int FLAG, job;
  252.   extern char c;
  253.   extern FILE *in, *out;
  254.   int LOADER(), CPU(), INTERRUPT(), 
  255.       nextjob(), io_operation(),
  256.       card_check,  /* check the cardreader is finished
  257.                       or not */
  258.       startadd,    /* the beginning address of the 
  259.                       executing program */
  260.       end;         /* ensure the read/write action */
  261.   short icmode;    /* interrupt condition code */
  262.   void _error(), output_format(), listresult(), reset();
  263.  
  264.   if (c == 'I') {
  265.      fscanf(in,"%04x %04x %04x %04x",&L0,&L1,&L2,&L3);
  266.      card_check = TRUE;
  267.   }
  268.   else {
  269.          _error(2);
  270.          exit(11);
  271.   }
  272.   while (card_check) { /* until all jobs finish */
  273.         jobid++;
  274.         fprintf(out,"\n******************************");
  275.         fprintf(out,"**************************\n\n");
  276.         fprintf(out,">>>>>>>>>>       JOB ID %4x  ",
  277.                 jobid);
  278.         fprintf(out,"COMMENCES       <<<<<<<<<<\n\n");
  279.         LOADER(&startadd,&trace,&FLAG);
  280.         if (FLAG) {   /* load input data has no error */
  281.            if (trace) output_format();
  282.            do {
  283.                 CPU(startadd,trace);
  284.                 icmode = PSW.index.ic;
  285.                 if (icmode == 1)   io_operation();
  286.                 end = INTERRUPT(icmode,&startadd);
  287.            } while (end && FLAG);
  288.            listresult();
  289.            reset();
  290.         }
  291.         c = getc(in);
  292.         while ((c != 'I') && (c != EOF))
  293.               c = getc(in);
  294.         card_check = nextjob();
  295.   }  /* end of while */
  296. }
  297.  
  298.  
  299.  
  300.  
  301. /*====================================================*
  302.  *                      LOADER                        *
  303.  *====================================================*/
  304. LOADER(beginadd,dump,OK)
  305. int *beginadd,      /* starting address */
  306.     *dump,          /* trace bit value */
  307.     *OK;            /* FLAG value */
  308. {
  309.   /* The LOADER module is responsible for loading the
  310.    * user program from simulated hardware module--
  311.    * card reader, and stores it into main memory. If
  312.    * any error being detected, then LOADER will return
  313.    * to the calling program and list the error message.
  314.    */
  315.  
  316.   extern char c;
  317.   extern FILE *in;
  318.   int  counter = 0,   /* code length variable */
  319.        turn,  /* boolean value for digit or 'A/a to F/f' */
  320.        STOP = FALSE,  /* while loop boolean variable */
  321.        next,   /* true: read next char */
  322.        /* variable name */
  323.        remainder, temp = 0, data, value,
  324.        i, j,   /* loop counter variable name */
  325.        follow, /* trace bit value */
  326.        flag = TRUE,   /* boolean variable */
  327.        MEMORY();
  328.   unsigned add_ptr = 0;  /* the next instruction 
  329.                             address */
  330.   void load_seg_reg(), _error();
  331.  
  332.   load_seg_reg();
  333.   c = getc(in);
  334.   while (isspace(c))  c = getc(in);
  335.   if (isdigit(c))  turn = FALSE;
  336.   else turn = TRUE;
  337.   next = TRUE;
  338.   while (!STOP)
  339.     switch (turn) {
  340.         case 0:
  341.               if (next) {
  342.                  temp = (c - '0') * 16;
  343.                  fscanf(in,"%c",&c);
  344.                  next = FALSE;
  345.                  if (!isdigit(c))  turn = TRUE;
  346.               }
  347.               else {
  348.                 temp = temp + (c - '0');
  349.                 remainder = temp % 8;
  350.                 temp = temp / 8;
  351.                 if (remainder > 0) {
  352.                    counter = counter + temp + 1;
  353.                    temp += 1;
  354.                 }
  355.                 else  counter += temp;
  356.                 if (counter <= ciow[0].seg.length) {
  357.                    for (i = 0; i < temp; i++) {
  358.                        fscanf(in,"%08x",&data);
  359.                        MEMORY(WRITE,add_ptr,&data);
  360.                        ++add_ptr;
  361.                    }
  362.                    remainder = 0;
  363.                    temp = 0;
  364.                    c = getc(in);
  365.                    while (isspace(c))  c = getc(in);
  366.                    if (!isxdigit(c))  STOP = TRUE;
  367.                    else if (!isdigit(c))  turn = TRUE;
  368.                    next = TRUE;
  369.                 }
  370.                 else {
  371.                        _error(10);
  372.                        flag = FALSE;
  373.                        STOP = TRUE;
  374.                 }
  375.               }
  376.               break;
  377.         case 1: 
  378.               if (next) {
  379.                  switch (c) {
  380.                    case 'A': 
  381.                    case 'a':
  382.                            temp = 16 * 10;
  383.                            break;
  384.                    case 'B':
  385.                    case 'b':
  386.                            temp = 16 * 11;
  387.                            break;
  388.                    case 'C':
  389.                    case 'c':
  390.                            temp = 16 * 12;
  391.                            break;
  392.                    case 'D':
  393.                    case 'd':
  394.                            temp = 16 * 13;
  395.                            break;
  396.                    case 'E':
  397.                    case 'e':
  398.                            temp = 16 * 14;
  399.                            break;
  400.                    case 'F':
  401.                    case 'f':
  402.                            temp = 16 * 15;
  403.                            break;
  404.                  }
  405.                  c = getc(in);
  406.                  next = FALSE;
  407.                  if (isdigit(c))  turn = FALSE;
  408.               }
  409.               else {
  410.                  switch (c) {
  411.                     case 'A':
  412.                     case 'a': 
  413.                             temp += 10;
  414.                             break;
  415.                     case 'B':
  416.                     case 'b':
  417.                             temp += 11;
  418.                             break;
  419.                     case 'C':
  420.                     case 'c':
  421.                             temp += 12;
  422.                             break;
  423.                     case 'D':
  424.                     case 'd':
  425.                             temp += 13;
  426.                             break;
  427.                     case 'E':
  428.                     case 'e':
  429.                             temp += 14;
  430.                             break;
  431.                     case 'F':
  432.                     case 'f':
  433.                             temp += 15;
  434.                             break;
  435.                  }
  436.                  remainder = temp % 8;
  437.                  temp /= 8;
  438.                  if (remainder > 0) {
  439.                     counter = counter + temp + 1;
  440.                     temp += 1;
  441.                  }
  442.                  else  counter += temp;
  443.                  if (counter <= ciow[0].seg.length) {
  444.                     for (i = 0; i < temp; i++) {
  445.                         fscanf(in,"%08x",&data);
  446.                         MEMORY(WRITE,add_ptr,&data);
  447.                         ++add_ptr;
  448.                     }
  449.                     remainder = 0;
  450.                     temp = 0;
  451.                     fscanf(in,"%c",&c);
  452.                     if (!isxdigit(c))  STOP = TRUE;
  453.                     else if (isdigit(c))  turn = FALSE;
  454.                     next = TRUE;
  455.                  }
  456.                  else {
  457.                         _error(10);
  458.                         flag = FALSE;
  459.                         STOP = TRUE;
  460.                  }
  461.               }
  462.               break;
  463.     } /* end of switch */
  464.   fscanf(in,"%c",&c);
  465.   if (c == 'K')  fscanf(in,"%c",&c);
  466.   if (flag) {
  467.      fscanf(in,"%04x",&counter);
  468.      add_ptr = ciow[3].seg.base;
  469.      for (i = 0; i < counter; i++) {
  470.          fscanf(in,"%04x %08x",&temp,&data);
  471.          MEMORY(WRITE,add_ptr,&data);
  472.          ++add_ptr;
  473.      }
  474.      fscanf(in,"%04x %d",&temp,&follow);
  475.      *dump = follow;
  476.      *beginadd = temp / 4;
  477.      *OK = flag;
  478.   } /* end of if */
  479.   else *OK = FALSE;
  480. }
  481.  
  482.            
  483.  
  484.  
  485. /*====================================================*
  486.  *                  load_seg_reg                      *
  487.  *====================================================*/
  488. void load_seg_reg()
  489. {
  490.   /* This function read the data, both base and length, 
  491.    * and store in the code, input, output and workspace
  492.    * segment origin register.
  493.    */   
  494.  
  495.   extern FILE *in;
  496.   extern int L0, base0, L1, base1, L2, base2,   
  497.          L3, base3;   
  498.  
  499.   L0 = L0 >> 2;
  500.   L1 = L1 >> 2;
  501.   L2 = L2 >> 2;
  502.   L3 = L3 >> 2;
  503.   base0 = 0;
  504.   base1 = L0;
  505.   base2 = base1 + L1;
  506.   base3 = base2 + L2;
  507.   ciow[0].seg.base   = base0;
  508.   ciow[0].seg.length = L0;
  509.   ciow[1].seg.base   = base1;
  510.   ciow[1].seg.length = L1;
  511.   ciow[2].seg.base   = base2;
  512.   ciow[2].seg.length = L2;
  513.   ciow[3].seg.base   = base3;
  514.   ciow[3].seg.length = L3;
  515. }
  516.  
  517.  
  518.  
  519.  
  520. /*====================================================*
  521.  *                      MEMORY                        *
  522.  *====================================================*/
  523. MEMORY(type,address,data)
  524. int type,
  525.     *data;
  526. unsigned address;
  527. {
  528.   /* The memory function performs the read/write
  529.    * operation, and extracts/stores data in main
  530.    * memory.
  531.    */   
  532.  
  533.   extern unsigned MEM[maxsize];
  534.   
  535.   switch (type) {
  536.          case WRITE : MEM[address] = *data;
  537.                       break;
  538.          case READ  : *data = MEM[address];
  539.                       break;
  540.   }
  541. }
  542.  
  543.  
  544.  
  545.  
  546. /*====================================================*
  547.  *                       CPU                          *
  548.  *====================================================*/
  549. CPU(address,trace)
  550. int address, trace;
  551. {
  552.   /* The CPU function will loop indefinitely fetching,
  553.    * decoding, and executing instructions until a HLT
  554.    * instruction or other exceptional condition occurs.
  555.    */   
  556.  
  557.   int RUN = TRUE,
  558.       contents,
  559.       MEMORY(), determine_mne(), compare(), multiply(),
  560.       move(), readdata(), substraction(), writedata(),
  561.       branch();
  562.   unsigned maskbit, PC;
  563.   short opcode;
  564.   void dump(); 
  565.  
  566.   PSW.value = (unsigned) address;
  567.   while (RUN) {
  568.         PC = PSW.index.pc;
  569.         /* fetch instruction */
  570.         MEMORY(READ,PC,&contents); 
  571.         PSW.index.pc += 1;     /* increment PC */
  572.         IR.value = contents;          
  573.         opcode = IR.gi.op;
  574.         determine_mne();  /* find the mne string name */
  575.         if (trace)   dump();
  576.         switch (opcode) { /* executes the instruction */
  577.                case 0  : 
  578.                        break;
  579.                case 1  :
  580.                        add();
  581.                        break;
  582.                case 4  :
  583.                        move();
  584.                        break;
  585.                case 11 :
  586.                        branch();
  587.                        break;
  588.                case 24 :
  589.                        multiply();
  590.                        break;
  591.                case 27 :
  592.                        readdata();
  593.                        break;
  594.                case 33 :
  595.                        substraction();
  596.                        break;
  597.                case 42 :
  598.                        compare();
  599.                        break;
  600.                case 51 :
  601.                        writedata();
  602.                        break;
  603.                case 63 :
  604.                        PSW.index.ic = 4;
  605.                        break;
  606.                default :
  607.                        PSW.index.ic = 5;
  608.                        break;
  609.         } /* end of switch */
  610.         if ((PSW.index.ic != 0) && (PSW.index.ic != 2))
  611.            RUN = FALSE;
  612.   } /* end of while */
  613. }
  614.  
  615.  
  616.  
  617.  
  618. /*====================================================*
  619.  *                 output_format                      *
  620.  *====================================================*/
  621. void output_format()
  622. {
  623.   extern FILE *out;
  624.  
  625.   fprintf(out,">>>>>>>>>>            MEMORY DUMP     ");
  626.   fprintf(out,"        <<<<<<<<<<\n\n");
  627.   fprintf(out,"COMMENTS : THE VALUE OF OPERAND1'S");
  628.   fprintf(out,"/OPERAND2'S IS IT'S\n");
  629.   fprintf(out,"           CONTENTS OF MEMORY OF THE");
  630.   fprintf(out," EFFECTIVE ADDRESS\n\n");
  631.   fprintf(out,"   PSW       IR    TYPE MNE   ");
  632.   fprintf(out,"OP1       OP2       CLOCK\n\n");
  633. }
  634.  
  635.  
  636.  
  637.  
  638. /*====================================================*
  639.  *                  determine_mne                     *
  640.  *====================================================*/
  641. determine_mne()
  642. {
  643.   /* use the opcode to distinguish the instruction 
  644.    * name. 
  645.    */
  646.  
  647.   extern char *mne;
  648.   extern int clock;
  649.   short opcode;
  650.  
  651.   opcode = IR.gi.op;
  652.   switch (opcode) {    /* increment clock */
  653.          case 0  :
  654.                  clock += 4;
  655.                  mne = "NOP";
  656.                  break;
  657.          case 1  :
  658.                  clock += 4;
  659.                  mne = "ADD";
  660.                  break;
  661.          case 4  :
  662.                  clock += 4;
  663.                  mne = "MOV";
  664.                  break;
  665.          case 11 :
  666.                  clock += 1;
  667.                  determine_maskmode();
  668.                  mne = "BC ";
  669.                  break;
  670.          case 24 :
  671.                  clock += 4;
  672.                  mne = "MLT";
  673.                  break;
  674.          case 27 :
  675.                  clock += 4;
  676.                  mne = "RD ";
  677.                  break;
  678.          case 33 :
  679.                  clock += 4;
  680.                  mne = "SUB";
  681.                  break;
  682.          case 42 :
  683.                  clock += 4;
  684.                  mne = "CMP";
  685.                  break;
  686.          case 51 :
  687.                  clock += 4;
  688.                  mne = "WR ";
  689.                  break;
  690.          case 63 :
  691.                  clock += 4;
  692.                  mne = "HLT";
  693.                  break;
  694.          default :
  695.                  clock += 4;
  696.                  mne = "   ";
  697.                  break;
  698.   } /* end of switch */
  699. }
  700.  
  701.  
  702.  
  703.  
  704. /*====================================================*
  705.  *                       dump                         *
  706.  *====================================================*/
  707. void dump()
  708. {
  709.   /* print out the contents */
  710.   
  711.   extern int clock;
  712.   extern FILE *out;
  713.   extern char *mne;
  714.   short opcode;
  715.   unsigned operand1, operand2, temp1, temp2;
  716.   int MEMORY();
  717.   char *type1 = "GI",
  718.        *type2 = "BI";
  719.   static char *blank = "         ";
  720.  
  721.   opcode = IR.gi.op;
  722.   operand1 = ciow[IR.gi.s1].seg.base + (IR.gi.d1 / 4);
  723.   operand2 = ciow[IR.gi.s2].seg.base + (IR.gi.d2 / 4);
  724.   MEMORY(READ,operand1,&temp1);
  725.   MEMORY(READ,operand2,&temp2);
  726.   PSW.index.pc = PSW.index.pc * 4;
  727.   if (opcode != 11) {
  728.      switch (opcode) {
  729.          case  0  :
  730.          case  63 :
  731.                   fprintf(out,"%08x  %08x  %s  %s ",
  732.                           PSW.value,IR.value,type1,mne);
  733.                   fprintf(out,"%s  %s%08x\n",blank,
  734.                           blank,clock);
  735.                   break;
  736.          case  27 :
  737.          case  51 :
  738.                   fprintf(out,"%08x  %08x  %s  %s ",
  739.                           PSW.value,IR.value,type1,mne);
  740.                   fprintf(out,"%s %08x  %08x\n",
  741.                           blank,temp2,clock);
  742.                   break;
  743.          case  1  :  
  744.          case  4  :
  745.          case  24 :
  746.          case  33 :
  747.          case  42 :
  748.                   fprintf(out,"%08x  %08x  %s  %s ",
  749.                           PSW.value,IR.value,type1,mne);
  750.                   fprintf(out,"%08x  %08x  %08x\n",
  751.                           temp1,temp2,clock);
  752.                   break;
  753.      } /* end of switch */
  754.   }
  755.   else { 
  756.          operand1 = ciow[IR.bi.s1].seg.base +
  757.                     (IR.bi.d1 / 4);
  758.          MEMORY(READ,operand1,&temp1);
  759.          fprintf(out,"%08x  %08x  %s  %s ",PSW.value,
  760.                  IR.value,type2,mne);
  761.          fprintf(out,"%08x     %s %08x\n",
  762.                  temp1,maskmode,clock);
  763.   }
  764.   PSW.index.pc = PSW.index.pc / 4;
  765. }
  766.  
  767.  
  768.  
  769.  
  770. /*====================================================*
  771.  *               determine_maskmode                   *
  772.  *====================================================*/
  773. determine_maskmode()
  774. {
  775.   extern char *maskmode;
  776.   unsigned maskbit;
  777.  
  778.   maskbit = IR.bi.mask;
  779.   switch (maskbit) {
  780.          case 0  : 
  781.                  maskmode = " 0000 ";
  782.                  break;
  783.          case 1  :
  784.                  maskmode = " 0001 ";
  785.                  break;
  786.          case 2  :
  787.                  maskmode = " 0010 ";
  788.                  break;
  789.          case 3  :
  790.                  maskmode = " 0011 ";
  791.                  break;
  792.          case 4  :
  793.                  maskmode = " 0100 ";
  794.                  break;
  795.          case 5  :
  796.                  maskmode = " 0101 ";
  797.                  break;
  798.          case 6  :
  799.                  maskmode = " 0110 ";
  800.                  break;
  801.          case 7  :
  802.                  maskmode = " 0111 ";
  803.                  break;
  804.          case 8  :
  805.                  maskmode = " 1000 ";
  806.                  break;
  807.          case 9  :
  808.                  maskmode = " 1001 ";
  809.                  break;
  810.          case 10 :
  811.                  maskmode = " 1010 ";
  812.                  break;
  813.          case 11 :
  814.                  maskmode = " 1011 ";
  815.                  break;
  816.          case 12 :
  817.                  maskmode = " 1100 ";
  818.                  break;
  819.          case 13 :
  820.                  maskmode = " 1101 ";
  821.                  break;
  822.          case 14 :
  823.                  maskmode = " 1110 ";
  824.                  break;
  825.          case 15 :
  826.                  maskmode = " 1111 ";
  827.                  break;
  828.   } /* end of switch */
  829. }
  830.  
  831.  
  832.  
  833.  
  834. /*====================================================*
  835.  *                       add                          *
  836.  *====================================================*/
  837. add()
  838. {
  839.   /* The add function simulates the ADD instruction
  840.    * operation.
  841.    */
  842.  
  843.   int value1, value2, flag = TRUE, temp, MEMORY(),
  844.       check(), condition_code();
  845.   unsigned operand1, operand2;
  846.  
  847.   operand1 = ciow[IR.gi.s1].seg.base + (IR.gi.d1 / 4);
  848.   operand2 = ciow[IR.gi.s2].seg.base + (IR.gi.d2 / 4);
  849.   check(&flag);
  850.   if (flag) {
  851.      MEMORY(READ,operand1,&value1);
  852.      MEMORY(READ,operand2,&value2);
  853.      temp = value1 + value2;
  854.      MEMORY(WRITE,operand1,&temp);
  855.      condition_code(temp);
  856.   }
  857. }
  858.  
  859.  
  860.  
  861.  
  862. /*====================================================*
  863.  *                     multiply                       *
  864.  *====================================================*/
  865. multiply()
  866. {
  867.   /* The multiply function simulates the MLT 
  868.    * instruction operation.
  869.    */
  870.  
  871.   int value1, value2,
  872.       flag = TRUE,
  873.       MEMORY(), check(), condition_code(),
  874.       temp;
  875.   unsigned operand1, operand2;
  876.   
  877.   operand1 = ciow[IR.gi.s1].seg.base + (IR.gi.d1 / 4);
  878.   operand2 = ciow[IR.gi.s2].seg.base + (IR.gi.d2 / 4);
  879.   check(&flag);
  880.   if (flag) {
  881.      MEMORY(READ,operand1,&value1);
  882.      MEMORY(READ,operand2,&value2);
  883.      temp = value1 * value2;
  884.      MEMORY(WRITE,operand1,&temp);
  885.      condition_code(temp);
  886.   }
  887. }
  888.  
  889.  
  890.  
  891.  
  892. /*====================================================*
  893.  *                      compare                       *
  894.  *====================================================*/
  895. compare()
  896. {
  897.   /* The compare function simulates the CMP instruction
  898.    * operation. 
  899.    */
  900.  
  901.   int MEMORY(), check(), condition_code(), value1,
  902.       value2, flag = TRUE;
  903.   unsigned operand1, operand2;
  904.  
  905.   operand1 = ciow[IR.gi.s1].seg.base + (IR.gi.d1 / 4);
  906.   operand2 = ciow[IR.gi.s2].seg.base + (IR.gi.d2 / 4);
  907.   check(&flag);
  908.   if (flag) {
  909.      MEMORY(READ,operand1,&value1);
  910.      MEMORY(READ,operand2,&value2);
  911.      if (value1 == value2)  PSW.index.cc = 8;
  912.      else if (value1 < value2)  PSW.index.cc = 4;
  913.           else  PSW.index.cc = 2;
  914.   }
  915. }
  916.  
  917.  
  918.  
  919.  
  920. /*====================================================*
  921.  *                       move                         *
  922.  *====================================================*/
  923. move()
  924. {
  925.   /* The move function simulates the MOV instruction
  926.    * operation.
  927.    */
  928.  
  929.   int check(), MEMORY(), condition_code(), value2,
  930.       flag = TRUE;
  931.   unsigned operand1, operand2;
  932.  
  933.   operand1 = ciow[IR.gi.s1].seg.base + (IR.gi.d1 / 4);
  934.   operand2 = ciow[IR.gi.s2].seg.base + (IR.gi.d2 / 4);
  935.   check(&flag);
  936.   if (flag) {
  937.      MEMORY(READ,operand2,&value2);
  938.      MEMORY(WRITE,operand1,&value2);
  939.      condition_code(value2);
  940.   }
  941. }
  942.  
  943.  
  944.  
  945.  
  946. /*====================================================*
  947.  *                    readdata                        *
  948.  *====================================================*/
  949. readdata()
  950. {
  951.   /* The readdata function simulates the RD 
  952.    * instruction operation. 
  953.    */
  954.  
  955.   extern int FLAG, rwsignal;
  956.   extern unsigned CHANNEL;
  957.   int flag = TRUE;
  958.   unsigned operand2, bound2;
  959.  
  960.   operand2 = ciow[IR.gi.s2].seg.base * 4 + IR.gi.d2;
  961.   bound2 = ciow[IR.gi.s2].seg.length * 4;
  962.   if (IR.gi.d2 > bound2-1) {
  963.      FLAG = flag = FALSE;
  964.      PSW.index.ic = 7;
  965.   }
  966.   if ((operand2 % 4) != 0) {
  967.      PSW.index.ic = 3;
  968.      FLAG = flag = FALSE;
  969.   }
  970.   if (flag) {
  971.      CHANNEL = operand2 / 4;
  972.      rwsignal = 1;
  973.      PSW.index.ic = 1;
  974.   }
  975. }
  976.  
  977.  
  978.  
  979.  
  980. /*====================================================*
  981.  *                   substraction                     *
  982.  *====================================================*/
  983. substraction()
  984. {
  985.   /* The substraction function simulated the SUB
  986.    * instruction operation. 
  987.    */
  988.  
  989.   int check(), MEMORY(), condition_code(), value1, 
  990.       value2, flag = TRUE, temp;
  991.   unsigned operand1, operand2;
  992.    
  993.   operand1 = ciow[IR.gi.s1].seg.base + (IR.gi.d1 / 4);
  994.   operand2 = ciow[IR.gi.s2].seg.base + (IR.gi.d2 / 4);
  995.   check(&flag);
  996.   if (flag) {
  997.      MEMORY(READ,operand1,&value1);
  998.      MEMORY(READ,operand2,&value2);
  999.      temp = value1 - value2;
  1000.      MEMORY(WRITE,operand1,&temp);
  1001.      condition_code(temp);
  1002.   }
  1003. }
  1004.  
  1005.  
  1006.  
  1007.  
  1008. /*====================================================*
  1009.  *                    writedata                       *
  1010.  *====================================================*/
  1011. writedata()
  1012. {
  1013.   /* The writedata function simulates the WR 
  1014.    * instruction operation.
  1015.    */
  1016.  
  1017.   extern int FLAG, rwsignal;   
  1018.   extern unsigned CHANNEL;
  1019.   int flag = TRUE;
  1020.   unsigned operand2, bound2;
  1021.  
  1022.   operand2 = ciow[IR.gi.s2].seg.base * 4 + IR.gi.d2;
  1023.   bound2 = ciow[IR.gi.s2].seg.length * 4;
  1024.   if (IR.gi.d2 > bound2-1) {
  1025.      FLAG = flag = FALSE;
  1026.      PSW.index.ic = 7;
  1027.   }
  1028.   if ((operand2 % 4) != 0) {
  1029.      PSW.index.ic = 3;
  1030.      FLAG = flag = FALSE;
  1031.   }
  1032.   if (flag) {
  1033.      CHANNEL = operand2 / 4;
  1034.      rwsignal = 0;
  1035.      PSW.index.ic = 1;
  1036.   }  
  1037. }
  1038.  
  1039.  
  1040.  
  1041.  
  1042. /*====================================================*
  1043.  *                      branch                        *
  1044.  *====================================================*/
  1045. branch()
  1046. {
  1047.   /* The branch function simulates the BC 
  1048.    * instruction operation. 
  1049.    */
  1050.  
  1051.   extern int FLAG;
  1052.   unsigned bound1, operand1, maskbit;
  1053.   int flag = TRUE, temp;
  1054.  
  1055.   operand1 = ciow[IR.bi.s1].seg.base * 4 + IR.bi.d1;
  1056.   maskbit  = IR.bi.mask;
  1057.   bound1 = ciow[IR.bi.s1].seg.length * 4;
  1058.   if (IR.bi.d1 > bound1-1) {
  1059.      FLAG = flag = FALSE;
  1060.      PSW.index.ic = 7;
  1061.   }
  1062.   if ((operand1 % 4) != 0) {
  1063.      PSW.index.ic = 3;
  1064.      FLAG = flag = FALSE;
  1065.   }
  1066.   if (flag)
  1067.      if ((PSW.index.cc & maskbit) != 0)
  1068.         PSW.index.pc = operand1 / 4;
  1069. }
  1070.  
  1071.  
  1072.  
  1073.  
  1074. /*====================================================*
  1075.  *                      check                         * 
  1076.  *====================================================*/
  1077. check(flag)
  1078. int *flag;
  1079.   /* This function is used to check the memory address
  1080.    * reference whether is Boundary fault or Segment 
  1081.    * address fault. 
  1082.    */
  1083.  
  1084.   extern int FLAG;
  1085.   unsigned operand1, operand2,
  1086.            bound1,       /* buffer edge */
  1087.            bound2;       /* buffer edge */
  1088.  
  1089.   operand1 = ciow[IR.gi.s1].seg.base * 4 + IR.gi.d1;
  1090.   operand2 = ciow[IR.gi.s2].seg.base * 4 + IR.gi.d2;
  1091.   bound1 = ciow[IR.gi.s1].seg.length * 4;
  1092.   bound2 = ciow[IR.gi.s2].seg.length * 4;
  1093.   if ((IR.gi.d1 > bound1-1) && 
  1094.       (IR.gi.d2 > bound2-1)) {
  1095.      *flag = FALSE;
  1096.      PSW.index.ic = 7;
  1097.   }
  1098.   if (((operand1 % 4) != 0) || 
  1099.       ((operand2 % 4) != 0)) {
  1100.      PSW.index.ic = 3;
  1101.      FLAG = *flag = FALSE;
  1102.   }
  1103. }
  1104.  
  1105.  
  1106.  
  1107.  
  1108. /*====================================================*
  1109.  *                 condition_code                     *
  1110.  *====================================================*/
  1111. condition_code(value)
  1112. unsigned value;
  1113. {
  1114.   /* This function is used to check the condition
  1115.    * code and set the bit of PSW.index.cc if the 
  1116.    * condition is true.  
  1117.    */
  1118.  
  1119.   if (value == 0)  
  1120.      PSW.index.cc = 8;
  1121.   else if (value < 0)
  1122.           PSW.index.cc = 4;
  1123.        else if (value > maxint)
  1124.                PSW.index.cc = 1;
  1125.             else  PSW.index.cc = 2;
  1126. }
  1127.  
  1128.  
  1129.  
  1130.  
  1131. /*====================================================*
  1132.  *                    io_operation                    *
  1133.  *====================================================*/
  1134. io_operation()
  1135. {
  1136.   /* This function performs i/o operation: read data
  1137.    * from card reader or write data to the printer.
  1138.    */
  1139.  
  1140.   extern FILE *in, *out;
  1141.   extern int rwsignal;
  1142.   extern unsigned CHANNEL;
  1143.   int temp;
  1144.  
  1145.   if (rwsignal) {   /* read action */
  1146.      /* read from the card reader */
  1147.      fscanf(in,"%08x",&temp);
  1148.      /* put into the input buffer */
  1149.      MEMORY(WRITE,CHANNEL,&temp);
  1150.   }
  1151.   else {   /* write action */
  1152.     /* read data from the output buffer */
  1153.     MEMORY(READ,CHANNEL,&temp);
  1154.     /* write data into the line printer */
  1155.     fprintf(out,"\nLINE PRINTER :");
  1156.     fprintf(out," %08x\n\n",temp);
  1157.   }
  1158. }
  1159.  
  1160.  
  1161.  
  1162.  
  1163. /*====================================================*
  1164.  *                    INTERRUPT                       *
  1165.  *====================================================*/
  1166. int INTERRUPT(icmode,startadd)
  1167. short icmode;
  1168. int   *startadd;
  1169. {
  1170.   /* The INTERRUPT function serrves several 
  1171.    * conditions. When an interrupt fault is recognize
  1172.    * by the CPU, the IC field of the PSW is loaded with
  1173.    * the appropriate interrupt code and control returns
  1174.    * to the _SYSTEM module.
  1175.    */
  1176.  
  1177.   extern int clock, jobid;
  1178.   extern FILE *out;
  1179.   int finish = 0;
  1180.   void _error();
  1181.  
  1182.   switch (icmode) {
  1183.      case 1 :
  1184.             clock += 16;
  1185.             finish = 1;
  1186.             break;
  1187.      case 4 :
  1188.             fprintf(out,"\nJOB ID %d FINISHED ===>",jobid);
  1189.             fprintf(out,"  NORMAL TERMINATE\n\n");
  1190.             break;
  1191.      case 3 :
  1192.      case 5 :
  1193.      case 6 :
  1194.      case 7 :
  1195.             _error(5);
  1196.             break;
  1197.      default :
  1198.              _error(6);
  1199.              break;
  1200.   } /* end of switch */
  1201.   *startadd = PSW.index.pc;
  1202.   return finish;
  1203. }
  1204.  
  1205.  
  1206.  
  1207.  
  1208. /*====================================================*
  1209.  *                    listresult                      *
  1210.  *====================================================*/
  1211. void listresult()
  1212. {
  1213.   /* This routine will print the result of program's
  1214.    * execution or print error message by a normal
  1215.    * or an abnormal way.
  1216.    */
  1217.  
  1218.   extern int clock;
  1219.   void _error();
  1220.  
  1221.   switch (PSW.index.ic) {
  1222.          case 3  :
  1223.                  _error(4);
  1224.                  break;
  1225.          case 4  :
  1226.                  break;
  1227.          case 5  :
  1228.                  _error(8);
  1229.                  break;
  1230.          case 6  :
  1231.                  _error(7);
  1232.                  break;
  1233.          case 7  :
  1234.                  _error(9);
  1235.                  break;
  1236.   } /* end of switch */
  1237.   fprintf(out,"THE SPENDING OF CLOCK TIME UNITS ===> ");
  1238.   fprintf(out,"%08x \n",clock);
  1239. }
  1240.  
  1241.  
  1242.  
  1243.  
  1244. /*====================================================*
  1245.  *                      reset                         *
  1246.  *====================================================*/
  1247. void reset()
  1248. {
  1249.   /* This routine will clear the clock, trace, PSW,
  1250.    * IR, and origin instruction registers value.
  1251.    */
  1252.  
  1253.   extern int clock, trace, FLAG;
  1254.   int i;
  1255.  
  1256.   clock = 0;
  1257.   trace = 0;
  1258.   PSW.value = 0;
  1259.   IR.value  = 0;
  1260.   for (i = 0; i < 4; i++)
  1261.       ciow[i].value = 0;
  1262.   FLAG = 1;
  1263. }
  1264.  
  1265.  
  1266.  
  1267.  
  1268. /*====================================================*
  1269.  *                     _error                         *
  1270.  *====================================================*/
  1271. void _error(n)
  1272. int n;
  1273. {
  1274.   /* print out the error message */
  1275.  
  1276.   switch (n) {
  1277.      case 1 : 
  1278.             fprintf(out,"\nERROR_1: CAN NOT OPEN");
  1279.             fprintf(out," THE INPUT FILE.\n\n");
  1280.             break;
  1281.      case 2 :
  1282.             fprintf(out,"\nERROR_2: THE INPUT FILE");
  1283.             fprintf(out," IS EMPTY.\n\n");
  1284.             break;
  1285.      case 3 :
  1286.             fprintf(out,"\nERROR_3: CAN NOT OPEN THE");
  1287.             fprintf(out," OUTPUT FILE.\n\n");
  1288.             break;
  1289.      case 4 :
  1290.             fprintf(out,"\nERROR_4: BOUNDARY");
  1291.             fprintf(out," FAULT.\n\n");
  1292.             break;
  1293.      case 5 :
  1294.             fprintf(out,"\nERROR_5: JOB ID %d ",jobid);
  1295.             fprintf(out,"FINISHED ===>  ");
  1296.             fprintf(out,"  ABNORMAL TERMAINATE.\n\n");
  1297.              break;
  1298.      case 6 :
  1299.             fprintf(out,"\nERROR_6: NO SUCH CASE OF");
  1300.             fprintf(out," EXCEPTION.\n\n");
  1301.             break;
  1302.      case 7 :
  1303.             fprintf(out,"\nERROR_7: ATTEMPT TO DIVIDE");
  1304.             fprintf(out," BY ZERO.\n\n");
  1305.             break;
  1306.      case 8 :
  1307.             fprintf(out,"\nERROR_8: INVALID OPCODE.");
  1308.             fprintf(out,"\n\n");
  1309.             break;
  1310.      case 9 :
  1311.             fprintf(out,"\nERROR_9: SEGMENT ADDRESS");
  1312.             fprintf(out," FAULT.\n\n");
  1313.             break;
  1314.      case 10 : 
  1315.              fprintf(out,"\nERROR_10: INPUT CODE");
  1316.              fprintf(out," LENGTH IS TOO BIG.\n\n");
  1317.   } /* end of switch */
  1318. }
  1319.  
  1320.  
  1321.  
  1322.  
  1323. /*====================================================*
  1324.  *                    nextjob                         *
  1325.  *====================================================*/
  1326. int nextjob()
  1327. {
  1328.   /* This routine will read the code, input, output
  1329.    * and workspace information or EOF, and return value
  1330.    * 1 to the calling program if there is another job
  1331.    * available.
  1332.    */
  1333.  
  1334.   extern char c;
  1335.   extern FILE *in;
  1336.   int finish1 = FALSE,
  1337.       finish = FALSE,
  1338.       temp,
  1339.       data;
  1340.  
  1341.   while (!finish) {
  1342.         if (c != EOF) {
  1343.            fscanf(in," %04x %04x %04x %04x",&L0,&L1,&L2,&L3);
  1344.            finish = TRUE;
  1345.            finish1 = FALSE;
  1346.         }
  1347.         else {
  1348.                finish = TRUE;
  1349.                finish1 = TRUE;
  1350.         }
  1351.   } /* end of while */
  1352.   if (finish && finish1)
  1353.      return FALSE;
  1354.   else  return TRUE;
  1355. }
  1356.  
  1357.  
  1358.  
  1359.  
  1360. /*====================================================*
  1361.  *                    file_close                      *
  1362.  *====================================================*/
  1363. file_close()
  1364. {
  1365.   extern FILE *in, *out;
  1366.  
  1367.   fprintf(out,"\n\n\n<<<<<<<<<<<<<           ");
  1368.   fprintf(out,"   END             >>>>>>>>>>>>>");
  1369.   fprintf(out,"\n*****************************");
  1370.   fprintf(out,"***************************\n\n");
  1371.   fclose(in);
  1372.   fclose(out);
  1373. }
  1374.  
  1375.  
  1376.  
  1377.