home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / CROSSASM / 68ASMSIM.ZIP / simsrc / code1.c next >
Encoding:
C/C++ Source or Header  |  1989-04-09  |  8.7 KB  |  392 lines

  1.  
  2. /***************************** 68000 SIMULATOR ****************************
  3.  
  4. File Name: CODE1.C
  5. Version: 1.0
  6.  
  7. The instructions implemented in this file are the MOVE instructions:
  8.  
  9.    MOVE, MOVEP, MOVEA, MOVE_FR_SR, MOVE_TO_CCR, MOVE_TO_SR, MOVEM,
  10.    MOVE_USP, MOVEQ
  11.  
  12.  
  13. ***************************************************************************/
  14.  
  15.  
  16.  
  17. #include <stdio.h>
  18. #include "extern.h"         /* contains global "extern" declarations */
  19.  
  20.  
  21. /* the following two arrays specify the execution times of the MOVE
  22.     instruction, for byte/word operands and for long operands */
  23.  
  24. int    move_bw_times [12][9] = {
  25.             4,    4,    8,    8,    8,   12,   14,   12,   16 ,
  26.             4,    4,    8,    8,    8,   12,   14,   12,   16 ,
  27.             8,    8,   12,   12,   12,   16,   18,   16,   20 ,
  28.             8,    8,   12,   12,   12,   16,   18,   16,   20 ,
  29.            10,   10,   14,   14,   14,   18,   20,   18,   22 ,
  30.            12,   12,   16,   16,   16,   20,   22,   20,   24 ,
  31.            14,   14,   18,   18,   18,   22,   24,   22,   26 ,
  32.            12,   12,   16,   16,   16,   20,   22,   20,   24 ,
  33.            16,   16,   20,   20,   20,   24,   26,   24,   28 ,
  34.            12,   12,   16,   16,   16,   20,   22,   20,   24 ,
  35.            14,   14,   18,   18,   18,   22,   24,   22,   26 ,
  36.             8,    8,   12,   12,   12,   16,   18,   16,   20   };
  37.  
  38.  
  39. int    move_l_times [12][9] = {
  40.             4,    4,   12,   12,   12,   16,   18,   16,   20 ,
  41.             4,    4,   12,   12,   12,   16,   18,   16,   20 ,
  42.            12,   12,   20,   20,   20,   24,   26,   24,   28 ,
  43.            12,   12,   20,   20,   20,   24,   26,   24,   28 ,
  44.            14,   14,   22,   22,   22,   26,   28,   26,   30 ,
  45.            16,   16,   24,   24,   24,   28,   30,   28,   32 ,
  46.            18,   18,   26,   26,   26,   30,   32,   30,   34 ,
  47.            16,   16,   24,   24,   24,   28,   30,   28,   32 ,
  48.            20,   20,   28,   28,   28,   32,   34,   32,   36 ,
  49.            16,   16,   24,   24,   24,   28,   30,   28,   32 ,
  50.            18,   18,   26,   26,   26,   30,   32,   30,   34 ,
  51.            12,   12,   20,   20,   20,   24,   26,   24,   28   };
  52.  
  53.  
  54. /* the following two arrays specify the instruction execution times
  55.     for the MOVEM instruction for memory-to-reg and reg-to-memory cases */
  56.  
  57. int     movem_t_r_times[11] = {
  58.         0,    0,    12,   12,    0,   16,   18,   16,   20,   16,   18  };
  59.  
  60. int     mover_t_m_times[11] = {
  61.         0,    0,     8,    0,    8,   12,   14,   12,   16,    0,    0  };
  62.         
  63.  
  64.  
  65. int    MOVE()
  66. {
  67. long    size;                /* 'size' holds the instruction size */
  68. int    src, dst;        /* 'src' and 'dst' hold the addressing mode codes */
  69.                             /* for instruction execution time computation */
  70.  
  71. /* MOVE has a different format for size field than all other instructions */
  72. /* so we can't use the 'decode_size' function */
  73. switch ( (inst >> 12) & 0x03)    
  74.     {
  75.     case 0x01 : size = BYTE;                /* bit pattern '01' */
  76.                  break;
  77.     case 0x03 : size = WORD;                /* bit pattern '10' */
  78.                  break;
  79.     case 0x02 : size = LONG;                /* bit pattern '11' */
  80.                  break;
  81.     default   : return (BAD_INST);        /* bad size field */
  82.                break;
  83.     }
  84.  
  85. /* the following gets the effective addresses for the source and destination
  86.     operands */
  87. if ( (eff_addr (size, ALL_ADDR, FALSE)) ||
  88.      (eff_addr (size, DATA_ALT_ADDR, FALSE)) )
  89.     return (BAD_INST);   /* if bad address format then return */
  90.                                 /* the code for 'bad instruction' */
  91.  
  92. dest = EV2;                                /* set 'dest' for use in 'cc_update' */
  93.  
  94. put (EA2, EV1, size);                /* perform the move to '*EA2' */
  95. value_of (EA2, &EV2, size);        /* set 'EV2' for use in 'cc_update' */
  96.  
  97. src = eff_addr_code(inst,0);        /* get the addressing mode codes */
  98. dst = eff_addr_code(inst,6);
  99.  
  100. if (size == LONG)            /* use the codes in instruction time computation */
  101.     inc_cyc (move_l_times [src] [dst]);
  102. else
  103.     inc_cyc (move_bw_times [src] [dst]);
  104.  
  105. /* now update the condition codes */
  106. cc_update (N_A, GEN, GEN, ZER, ZER, EV1, dest, EV2, size, 0);
  107.  
  108. /* return the value for 'success' */
  109. return SUCCESS;
  110.  
  111. }
  112.  
  113.  
  114.  
  115. int    MOVEP()
  116. {
  117. int    address, Dx, disp, count, direction, reg;
  118. long    temp, size;
  119.  
  120. mem_request (&PC, (long) WORD, &temp);
  121. from_2s_comp (temp, (long) WORD, &temp);
  122.  
  123. address = A[a_reg(inst&0x07)] + (temp & WORD);
  124.  
  125. direction = inst & 0x80;
  126.  
  127. if (inst & 0x40)
  128.     {
  129.     size = LONG;
  130.     count = 4;
  131.     }
  132. else
  133.     {
  134.     size = WORD;
  135.     count = 2;
  136.     }
  137.  
  138. reg = (inst >> 9) & 0x07;
  139. Dx = D[reg] & size;
  140.  
  141. for (;count > 0; count--)
  142.     {
  143.     disp = 8 * (count - 1);
  144.     if (direction)
  145.         mem_put ( (long)((Dx >> disp) & BYTE) , address, (long) BYTE);
  146.     else
  147.         {
  148.         mem_req (address, (long) BYTE, &temp);
  149.         switch  (count) {
  150.             case 4 :    D[reg] = (D[reg] & 0x00ffffff) | (temp * 0x1000000);
  151.                         break;
  152.             case 3 :    D[reg] = (D[reg] & 0xff00ffff) | (temp * 0x10000);
  153.                         break;
  154.             case 2 :    D[reg] = (D[reg] & 0xffff00ff) | (temp * 0x100);
  155.                         break;
  156.             case 1 : D[reg] = (D[reg] & 0xffffff00) | (temp);
  157.                         break;
  158.             }
  159.         }
  160.     address += 2;
  161.     }
  162.  
  163. inc_cyc ( (size == LONG) ? 24 : 16);
  164.  
  165. return SUCCESS;
  166.  
  167. }
  168.  
  169.  
  170.  
  171. int    MOVEA()
  172. {
  173. long    size;
  174. int    src;
  175.  
  176. if (inst & 0x1000)
  177.     size = WORD;
  178. else
  179.     size = LONG;
  180.  
  181. src = eff_addr_code(inst,0);
  182. if (size == WORD)
  183.     inc_cyc (move_bw_times[src][2]);
  184. else
  185.     inc_cyc (move_l_times[src][2]);
  186.  
  187. if (eff_addr(size, ALL_ADDR, FALSE))
  188.     return (BAD_INST);
  189.  
  190. if (size == WORD) 
  191.     sign_extend ((int)EV1, (long) WORD, &EV1);
  192.  
  193. A[a_reg((inst >> 9) & 0x07)] = EV1;
  194.  
  195. return SUCCESS;
  196.  
  197. }
  198.  
  199.  
  200.  
  201. int    MOVE_FR_SR()
  202. {
  203.  
  204. if (eff_addr ((long) WORD, DATA_ALT_ADDR, TRUE))
  205.     return (BAD_INST);
  206.  
  207. put (EA1, (long) SR, (long) WORD);
  208.  
  209. inc_cyc ((inst & 0x0030) ? 8 : 6);
  210.  
  211. return SUCCESS;
  212.  
  213. }
  214.  
  215.  
  216.  
  217. int    MOVE_TO_CCR()
  218. {
  219.  
  220. if (eff_addr ((long) WORD, DATA_ADDR, TRUE))
  221.     return (BAD_INST);
  222.  
  223. put (&SR, EV1, (long) BYTE);
  224.  
  225. inc_cyc (12);
  226.  
  227. return SUCCESS;
  228.  
  229. }
  230.  
  231.  
  232.  
  233. int    MOVE_TO_SR()
  234. {
  235.  
  236. if (! (SR & sbit))
  237.     return (NO_PRIVILEGE);
  238.  
  239. if (eff_addr ((long) WORD, DATA_ADDR, TRUE))
  240.     return (BAD_INST);
  241.  
  242. put (&SR, EV1, (long) WORD);
  243.  
  244. inc_cyc (12);
  245.  
  246. return SUCCESS;
  247.  
  248. }
  249.  
  250.  
  251.  
  252. int    MOVEM()
  253. {
  254. int    direction, addr_modes_mask, counter, addr_mode;
  255. int    displacement, address, total_displacement;
  256. long    size, mask_list, temp;
  257.  
  258. mem_request (&PC, (long) WORD, &mask_list);
  259.  
  260. if (inst & 0x0040)
  261.     size = LONG;
  262. else
  263.     size = WORD;
  264.  
  265. if (direction = (inst & 0x0400))
  266.     addr_modes_mask = CONTROL_ADDR | bit_4;
  267. else
  268.     addr_modes_mask = CONT_ALT_ADDR | bit_5;
  269.  
  270. if (eff_addr (size, addr_modes_mask, FALSE))
  271.     return (BAD_INST);            /* bad effective address */
  272.  
  273. address = (long) ( (long)EA1 - (long)&memory[0]);
  274. total_displacement = address;
  275.  
  276. if ((inst & 0x0038) != 0x20)
  277.     {
  278.     if (size == WORD)
  279.         displacement = 2;
  280.     else
  281.         displacement = 4;
  282.     }
  283. else
  284.     {
  285.     if (size == WORD)
  286.         displacement = -2;
  287.     else
  288.         displacement = -4;
  289.     }
  290.  
  291. addr_mode = eff_addr_code (inst,0);
  292.  
  293. if (direction)
  294.     inc_cyc (movem_t_r_times[addr_mode]);        /* memory to registers */
  295. else
  296.     inc_cyc (mover_t_m_times[addr_mode]);        /* registers to memory */
  297.  
  298. for (counter = 0; counter < 16; counter++)
  299.     if (mask_list & (1 << counter))
  300.         {
  301.         if (size == LONG)
  302.             inc_cyc (8);
  303.         else
  304.             inc_cyc (4);
  305.         if (direction)
  306.             {
  307.             if (size == WORD)        /* if size is WORD then sign-extend */
  308.                 {
  309.                 mem_req (address, (long) WORD, &temp);
  310.                 sign_extend ((int) temp, LONG, &temp);
  311.                 }
  312.             if (counter < 8)
  313.                 D[counter] = temp;
  314.             else
  315.                 A[a_reg(counter - 8)] = temp;
  316.             }
  317.         else
  318.             {
  319.             if ((inst & 0x38) == 0x20)
  320.                 {
  321.                 if (counter < 8)
  322.                     mem_put (A[a_reg(7 - counter)], address, size);
  323.                 else
  324.                     mem_put (D[15 - counter], address, size);
  325.                 }
  326.             else
  327.                 {
  328.                 if (counter < 8)
  329.                     mem_put (D[counter], address, size);
  330.                 else
  331.                     mem_put (A[a_reg(counter - 8)], address, size);
  332.                 }
  333.             }
  334.         address += displacement;
  335.         }
  336. address -= displacement;
  337. total_displacement = address - total_displacement;
  338.  
  339. /* if pre-decrement or post-increment modes then change the value */
  340. /* of the address register appropriately */
  341. if ( ((inst & 0x38) == 0x20) || ( (inst & 0x38) == 0x18) )
  342.     A[a_reg(inst & 0x7)] += total_displacement;
  343.  
  344. return SUCCESS;
  345.  
  346. }
  347.  
  348.  
  349.  
  350. int    MOVE_USP()
  351. {
  352. int    reg;
  353.  
  354. if (!(SR & sbit))
  355.     return (NO_PRIVILEGE);        /* supervisor state not on */
  356.  
  357. reg = inst & 0x7;
  358. if (reg == 7)
  359.     reg = 8;
  360.  
  361. if (inst & 0x8)
  362.     A[reg] = A[7];
  363. else
  364.     A[7] = A[reg];
  365.  
  366. inc_cyc (4);
  367.  
  368. return SUCCESS;
  369.  
  370. }
  371.  
  372.  
  373.  
  374. int    MOVEQ()
  375. {
  376. int    reg;
  377.  
  378. reg = (inst >> 9) & 0x7;
  379. source = inst & 0xff;
  380. dest = D[reg];
  381.  
  382. /* the data register is sign extended to a longword */
  383. sign_extend ((int)source, (long) BYTE, &D[reg]);
  384. sign_extend ((int)D[reg], (long) WORD, &D[reg]);
  385.  
  386. cc_update (N_A, GEN, GEN, ZER, ZER, source, dest, D[reg], LONG, 0);
  387. inc_cyc (4);
  388. return SUCCESS;
  389.  
  390. }
  391.  
  392.