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

  1.  
  2. /***************************** 68000 SIMULATOR ****************************
  3.  
  4. File Name: CODE7.C
  5. Version: 1.0
  6.  
  7. The instructions implemented in this file are shift and rotate operations:
  8.  
  9.         SHIFT_ROT (ASL, ASR, LSL, LSR, ROL, ROR, ROXL, ROXR), SWAP,
  10.         BIT_OP (BCHG, BCLR, BSET, BTST), TAS
  11.  
  12.  
  13. ***************************************************************************/
  14.  
  15.  
  16. #include <stdio.h>
  17. #include "extern.h"         /* contains global "extern" declarations */
  18.  
  19.  
  20.  
  21.  
  22. int    SHIFT_ROT()
  23. {
  24. long    size;
  25. int    reg, count_reg, shift_count, shift_size, type, counter, msb, mem_reg;
  26. int    direction, temp_bit, temp_bit_2;
  27.  
  28. if (mem_reg = ((inst & 0xc0) == 0xc0))
  29.     {
  30.     if (eff_addr ((long) WORD, MEM_ALT_ADDR, TRUE))
  31.         return (BAD_INST);        /* bad instruction format */
  32.     size = WORD;
  33.     shift_count = 1;
  34.     source = dest = EV1 & size;
  35.     type = (inst & 0x600) >> 9;
  36.     inc_cyc (8);
  37.     }
  38. else
  39.     {
  40.     if (decode_size(&size)) 
  41.         return (BAD_INST); /* bad instruction format */
  42.     if (inst & 0x20)
  43.         shift_count = D[(inst >> 9) & 0x7] % 64;
  44.     else
  45.         {
  46.         shift_count = (inst >> 9) & 0x7;
  47.         if (shift_count == 0)
  48.             shift_count = 8;
  49.         }
  50.     reg = inst & 7;
  51.     source = dest = D[reg] & size;
  52.     type = (inst & 0x18) >> 3;
  53.     EA1 = &D[reg];
  54.     value_of (EA1, &EV1, size);
  55.     if (size == LONG)
  56.         inc_cyc (8 + 2 * shift_count);
  57.     else
  58.         inc_cyc (6 + 2 * shift_count);
  59.     }
  60. direction = inst & 0x100;
  61. if (size == LONG)
  62.     shift_size = 31;
  63. else if (size == WORD)
  64.     shift_size = 15;
  65. else
  66.     shift_size = 7;
  67.  
  68. if (shift_count == 0)
  69.     {
  70.     if (type == 2)
  71.         cc_update (N_A, GEN, GEN, ZER, CASE_1, 
  72.             source, dest, EV1, size, shift_count);
  73.     else
  74.         cc_update (N_A, GEN, GEN, ZER, ZER, 
  75.             source, dest, EV1, size, shift_count);
  76.     }
  77. else
  78. switch (type) {
  79.     case 0 :                                             /* do an arithmetic shift */
  80.     if (direction) {            /* do a shift left */
  81.         put (EA1, (EV1 & size) << shift_count, size);
  82.         value_of (EA1, &EV1, size);
  83.         cc_update (GEN, GEN, GEN, CASE_4, CASE_3, 
  84.                 source, dest, EV1, size, shift_count);
  85.         }
  86.     else {        /* do a shift right */
  87.         /* do the shift replicating the most significant bit */
  88.         if ((EV1 >> shift_size) & 1)
  89.             temp_bit = 1;
  90.         else
  91.             temp_bit = 0;
  92.         for (counter = 1; counter <= shift_count; counter++)
  93.             {
  94.             put (EA1, (EV1 & size) >> 1, size);
  95.             value_of (EA1, &EV1, size);
  96.             if (temp_bit)
  97.                 put (EA1, EV1 | (1 << shift_size), size);
  98.             else
  99.                 put (EA1, EV1 & (~(1 << shift_size)), size);
  100.             value_of (EA1, &EV1, size);
  101.             }
  102.         cc_update (GEN, GEN, GEN, ZER, CASE_2, 
  103.                 source, dest, EV1, size, shift_count);
  104.         }
  105.       break;
  106.     case 1 :                                             /* do a logical shift */
  107.                 if (direction) {            /* do a shift left */
  108.                     put (EA1, EV1 << shift_count, size);
  109.                     value_of (EA1, &EV1, size);
  110.                     cc_update (GEN, GEN, GEN, ZER, CASE_3, 
  111.                             source, dest, EV1, size, shift_count);
  112.                     }
  113.                 else {        /* do a shift right */
  114.                     put (EA1, (EV1 & size) >> shift_count, size);
  115.                     value_of (EA1, &EV1, size);
  116.                     cc_update (GEN, GEN, GEN, ZER, CASE_2, 
  117.                             source, dest, EV1, size, shift_count);
  118.                     }
  119.             break;
  120.     case 2 :                                        /* do a rotate with extend */
  121.                 if (direction) {            /* do a rotate left */
  122.                     for (counter = 1; counter <= shift_count; counter++)
  123.                         {
  124.                         temp_bit = (EV1 >> shift_size) & 1;
  125.                         temp_bit_2 = (SR & xbit) >> 4;
  126.                         put (EA1, (EV1 & size) << 1, size);
  127.                         value_of (EA1, &EV1, size);
  128.                         if (temp_bit_2)
  129.                             put (EA1, EV1 | 1, size);
  130.                         else
  131.                             put (EA1, EV1 & ~1, size);
  132.                         value_of (EA1, &EV1, size);
  133.                         if (temp_bit)
  134.                             SR = SR | xbit;
  135.                         else
  136.                             SR = SR & ~xbit;
  137.                         }
  138.                     cc_update (GEN, GEN, GEN, ZER, CASE_3, 
  139.                             source, dest, EV1, size, shift_count);
  140.                     }
  141.                 else {        /* do a rotate right */
  142.                     for (counter = 1; counter <= shift_count; counter++)
  143.                         {
  144.                         temp_bit = EV1 & 1;
  145.                         temp_bit_2 = (SR & xbit) >> 4;
  146.                         put (EA1, (EV1 & size) >> 1, size);
  147.                         value_of (EA1, &EV1, size);
  148.                         if (temp_bit_2)
  149.                             put (EA1, EV1 | (1 << shift_size), size);
  150.                         else
  151.                             put (EA1, EV1 & (~(1 << shift_size)), size);
  152.                         value_of (EA1, &EV1, size);
  153.                         if (temp_bit)
  154.                             SR = SR | xbit;
  155.                         else
  156.                             SR = SR & ~xbit;
  157.                         }
  158.                     put (EA1, EV1, size);        
  159.                     cc_update (GEN, GEN, GEN, ZER, CASE_2, 
  160.                             source, dest, EV1, size, shift_count);
  161.                     }
  162.             break;
  163.     case 3 :                                             /* do a rotate */
  164.                 if (direction) {            /* do a rotate left */
  165.                     for (counter = 1; counter <= shift_count; counter++)
  166.                         {
  167.                         temp_bit = (EV1 >> shift_size) & 1;
  168.                         put (EA1, (EV1 & size) << 1, size);
  169.                         value_of (EA1, &EV1, size);
  170.                         if (temp_bit)
  171.                             put (EA1, EV1 | 1, size);
  172.                         else
  173.                             put (EA1, EV1 & ~1, size);
  174.                         value_of (EA1, &EV1, size);
  175.                         }
  176.                     cc_update (N_A, GEN, GEN, ZER, CASE_3, 
  177.                             source, dest, EV1, size, shift_count);
  178.                     }
  179.                 else {        /* do a rotate right */
  180.                     for (counter = 1; counter <= shift_count; counter++)
  181.                         {
  182.                         temp_bit = EV1 & 1;
  183.                         put (EA1, (EV1 & size) >> 1, size);
  184.                         value_of (EA1, &EV1, size);
  185.                         if (temp_bit)
  186.                             put (EA1, EV1 | (1 << shift_size), size);
  187.                         else
  188.                             put (EA1, EV1 & (~(1 << shift_size)), size);
  189.                         value_of (EA1, &EV1, size);
  190.                         }
  191.                     cc_update (N_A, GEN, GEN, ZER, CASE_2, 
  192.                             source, dest, EV1, size, shift_count);
  193.                     }
  194.             break;
  195.     }
  196.  
  197. return SUCCESS;
  198.  
  199. }
  200.  
  201.  
  202.  
  203. int    SWAP()
  204. {
  205. long    reg;
  206.  
  207. reg = inst & 0x07;
  208.  
  209. /* perform the SWAP operation */
  210. D[reg] = ((D[reg] & WORD) * 0x10000) | ((D[reg] & 0xffff0000) / 0x10000);
  211.  
  212. cc_update (N_A, GEN, GEN, ZER, ZER, source, dest, D[reg], LONG, 0);
  213.  
  214. inc_cyc (4);
  215.  
  216. return SUCCESS;
  217.  
  218. }
  219.  
  220.  
  221.  
  222. int    BIT_OP()
  223. {
  224. int    reg, mem_reg;
  225. long    size, bit_no;
  226.  
  227. if (inst & 0x100)
  228.     bit_no = D[(inst >> 9) & 0x07];
  229. else
  230.     {
  231.     mem_request (&PC, (long) WORD, &bit_no);
  232.     bit_no = bit_no & 0xff;
  233.     }
  234.  
  235. mem_reg = (inst & 0x38);
  236.  
  237. if (eff_addr ((long) BYTE, DATA_ADDR, TRUE))
  238.     return (BAD_INST);        /* bad instruction format */
  239.  
  240. if (mem_reg)
  241.     {
  242.     bit_no = bit_no % 8;
  243.     size = BYTE;
  244.     }
  245. else
  246.     {
  247.     bit_no = bit_no % 32;
  248.     size = LONG;
  249.     }
  250.  
  251. if ((EV1 >> bit_no) & 1)
  252.     SR = SR & (~zbit);
  253. else
  254.     SR = SR | zbit;
  255.  
  256. switch ((inst >> 6) & 0x3) {
  257.     case 0 :             /* perform a bit test operation */
  258.           if (mem_reg)
  259.             inc_cyc (4);
  260.           else
  261.             inc_cyc (6);
  262.           break;
  263.     case 1 :             /* perform a bit change operation */
  264.             if ((EV1 >> bit_no) & 1)
  265.                 put (EA1, *EA1 & (~(1 << bit_no)), size);
  266.             else
  267.                 put (EA1, *EA1 | (1 << bit_no), size);
  268.             inc_cyc (8);
  269.           break;
  270.     case 2 : /* perform a bit clear operation */
  271.             put (EA1, *EA1 & (~(1 << bit_no)), size);
  272.           if (mem_reg)
  273.             inc_cyc (8);
  274.           else
  275.             inc_cyc (10);
  276.           break;
  277.     case 3 : /* perform a bit set operation */
  278.             put (EA1, *EA1 | (1 << bit_no), size);
  279.             inc_cyc (8);
  280.           break;
  281.     }
  282.  
  283. if (mem_reg)
  284.     inc_cyc (4);
  285.  
  286. return SUCCESS;
  287.  
  288. }
  289.  
  290.  
  291.  
  292.  
  293. int    TAS()
  294. {
  295.  
  296. if (eff_addr ((long) BYTE, DATA_ALT_ADDR, TRUE))
  297.     return (BAD_INST);        /* bad effective address format */
  298.  
  299. /* perform the TAS operation */
  300. /* first set the condition codes according to *EA1 */
  301. cc_update (N_A, GEN, GEN, ZER, ZER, source, dest, *EA1, (long) BYTE, 0);
  302.  
  303. /* then set the high order bit of the *EA1 byte */
  304. put (EA1, EV1 | 0x80, (long) BYTE);
  305.  
  306. inc_cyc ((inst & 0x30) ? 10 : 4);
  307.  
  308. return SUCCESS;
  309.  
  310. }
  311.  
  312.