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

  1.  
  2. /***************************** 68000 SIMULATOR ****************************
  3.  
  4. File Name: CODE3.C
  5. Version: 1.0
  6.  
  7. The instructions implemented in this file are the integer arithmetic
  8.     operations:
  9.  
  10.         ADD, ADDA, ADDI, ADDQ, ADDX, SUB, SUBA, SUBI, SUBQ, SUBX
  11.  
  12.  
  13. ***************************************************************************/
  14.  
  15.  
  16. #include <stdio.h>
  17. #include "extern.h"         /* contains global "extern" declarations */
  18.  
  19.  
  20.  
  21.  
  22. int    ADD()
  23. {
  24. int    addr_modes_mask;            /* holds mask for use in 'eff_addr()' */
  25. int    reg;                            /* holds data register number */
  26. long    size;                            /* holds instruction size */
  27.  
  28. /* compute addressing modes mask from appropriate bit in instruction word */
  29. addr_modes_mask = (inst & 0x0100) ? MEM_ALT_ADDR : ALL_ADDR;
  30.  
  31. /* the following statement decodes the instruction size using */
  32. /* decode_size(), then decodes the effective address using eff_addr() */
  33. if ((decode_size(&size)) ||
  34.     (eff_addr (size, addr_modes_mask, TRUE)))
  35.     return (BAD_INST);            /* if size or effective address format */
  36.                                         /* is bad then return 'bad instruction' */
  37.  
  38. reg = (inst >> 9) & 0x0007;        /* get data register number */
  39.  
  40. /* now perform the addition according to instruction format */
  41. /* instruction bit 8 'on' means data register to effective-address */
  42. /* instruction bit 8 'off' means effective-address to data register */
  43. if (inst & 0x0100) {
  44.     source = D[reg];
  45.     dest = EV1;
  46.     put (EA1, source + dest, size);        /* use 'put' to deposit result */
  47.     value_of (EA1, &result, size);    /* set 'result' for use in 'cc_update' */
  48.     }
  49. else {
  50.     source = EV1;        /* get source. 'EV1' was set in 'eff_addr()' */
  51.     dest = D[reg];                                        /* get destination */
  52.     put (&D[reg], source + dest, size);
  53.     result = D[reg];                /* set 'result' for use in 'cc_update()' */
  54.     }
  55.  
  56. /* update the condition codes */
  57. cc_update (GEN, GEN, GEN, CASE_1, CASE_5, source, dest, result, size, 0);
  58.  
  59. /* now update the cycle counter appropriately depending on the instruction */
  60. /* size and the instruction format */
  61. if (inst & 0x0100) {
  62.     inc_cyc ( (size == LONG) ? 12 : 8);
  63.     }
  64. else {
  65.     if (size == LONG) {
  66.         if ( (!(inst & 0x0030)) || ((inst & 0x003f) == 0x003c) )
  67.             inc_cyc (8);
  68.         else
  69.             inc_cyc (6);
  70.         }
  71.     else {
  72.         inc_cyc (4);
  73.         }
  74.     }
  75.  
  76. /* return 'success' */
  77. return SUCCESS;
  78.  
  79. }
  80.  
  81.  
  82. int    ADDA()
  83. {
  84. long    size;
  85. int    reg;
  86.  
  87. if (inst & 0x0100)
  88.     size = LONG;
  89. else
  90.     size = WORD;
  91.  
  92. if (eff_addr (size, ALL_ADDR, TRUE))
  93.     return (BAD_INST);            /* bad instruction format */
  94.  
  95. reg = (inst >> 9) & 0x0007;
  96.  
  97. source = EV1;
  98. dest = A[a_reg(reg)];
  99.  
  100. put (&A[a_reg(reg)], source + dest, size);
  101.  
  102. if (size == LONG) {
  103.     if ( (!(inst & 0x0030)) || ((inst & 0x003f) == 0x003c) )
  104.         inc_cyc (8);
  105.     else
  106.         inc_cyc (6);
  107.     }
  108. else 
  109.     inc_cyc (8);
  110.  
  111. return SUCCESS;
  112.  
  113. }
  114.  
  115.  
  116.  
  117. int    ADDI()
  118. {
  119. long    size;
  120.  
  121. if (decode_size(&size))
  122.     return (BAD_INST);            /* bad instruction format */
  123.  
  124. mem_request (&PC, size, &source);
  125.  
  126. if (eff_addr (size, DATA_ALT_ADDR, TRUE))
  127.     return (BAD_INST);            /* bad instruction format */
  128.  
  129. dest = EV1;
  130.  
  131. put (EA1, source + dest, size);
  132. value_of (EA1, &result, size);
  133.  
  134. cc_update (GEN, GEN, GEN, CASE_1, CASE_5, source, dest, result, size, 0);
  135.  
  136. if (inst & 0x0038) {
  137.     inc_cyc ( (size == LONG) ? 20 : 12);
  138.     }
  139. else {
  140.     inc_cyc ( (size == LONG) ? 16 : 8);
  141.     }
  142.  
  143. return SUCCESS;
  144.  
  145. }
  146.  
  147.  
  148.  
  149. int    ADDQ()
  150. {
  151. long    size;
  152.  
  153. if (decode_size(&size))
  154.     return (BAD_INST);            /* bad size format */
  155.  
  156. if ((inst & 0x38) == 0x8)        /* if address reg direct, operation is long */
  157.     size == LONG;
  158.  
  159. if (eff_addr (size, ALTERABLE_ADDR, TRUE))
  160.     return (BAD_INST);            /* bad effectove address format */
  161.  
  162. source = ((inst >> 9) & 0x07);
  163. if (source == 0)             /* if source is '0', that corresponds to '8' */
  164.     source = 8;
  165.  
  166. dest = EV1;
  167.  
  168. put (EA1, source + dest, size);
  169. value_of (EA1, &result, size);
  170.  
  171. if (!((inst & 0x38) == 0x8))   /* if address reg direct, cc's not affected */
  172. cc_update (GEN, GEN, GEN, CASE_1, CASE_5, source, dest, result, size, 0);
  173.  
  174. switch (inst & 0x0038) {
  175.     case 0x0  : inc_cyc ( (size == LONG) ? 8 : 4);
  176.                 break;
  177.     case 0x1  : inc_cyc (8);
  178.                 break;
  179.     default   : inc_cyc ( (size == LONG) ? 12 : 8);
  180.                 break;
  181.     }
  182.  
  183. return SUCCESS;
  184.  
  185. }
  186.  
  187.  
  188.  
  189. int    ADDX()
  190. {
  191. long    size;
  192. int    Rx, Ry;
  193.  
  194. if (decode_size(&size)) return (BAD_INST);
  195.  
  196. Rx = (inst >> 9) & 0x0007;
  197. Ry = inst & 0x0007;
  198.  
  199. /* perform the ADDX operation */
  200. if (inst & 0x0008)
  201.     {
  202.     Rx = a_reg (Rx);
  203.     Ry = a_reg (Ry);
  204.     if (size == BYTE) {
  205.         A[Rx]--;
  206.        A[Ry]--;
  207.        }
  208.     if (size == WORD) {
  209.         A[Rx] -= 2;
  210.         A[Ry] -= 2;
  211.        }
  212.     if (size == LONG) {
  213.         A[Rx] -= 4;
  214.         A[Ry] -= 4;
  215.        }
  216.     mem_req ((int) A[Ry], size, &source);
  217.     mem_req ((int) A[Rx], size, &dest);
  218.     put (&memory[A[a_reg(Rx)]], source + dest + ((SR & xbit) >> 4), size);
  219.     mem_req ((int) A[Rx], size, &result);
  220.     }
  221. else
  222.     {
  223.     source = D[Ry] & size;
  224.     dest = D[Rx] & size;
  225.     put (&D[Rx], source + dest + ((SR & xbit) >> 4), size);
  226.     result = D[Rx] & size;
  227.     }
  228.  
  229. cc_update (GEN, GEN, CASE_1, CASE_1, CASE_5, source, dest, result, size, 0);
  230.  
  231. if (size == LONG)
  232.    inc_cyc ( (inst & 0x0008) ? 30 : 8);
  233. else
  234.    inc_cyc ( (inst & 0x0008) ? 18 : 4);
  235.  
  236. return SUCCESS;
  237.  
  238. }
  239.  
  240.  
  241.  
  242. int    SUB()
  243. {
  244. int    addr_modes_mask, reg;
  245. long    size;
  246.  
  247. addr_modes_mask = (inst & 0x0100) ? MEM_ALT_ADDR : ALL_ADDR;
  248.  
  249. if ((decode_size(&size)) ||
  250.     (eff_addr (size, addr_modes_mask, TRUE)))
  251.     return (BAD_INST);            /* bad instruction format */
  252.  
  253. reg = (inst >> 9) & 0x0007;
  254.  
  255. if (inst & 0x0100)
  256.     {
  257.     source = D[reg] & size;
  258.     dest = EV1 & size;
  259.     put (EA1, dest - source, size);
  260.     value_of (EA1, &result, size);
  261.     }
  262. else
  263.     {
  264.     source = EV1 & size;
  265.     dest = D[reg] & size;
  266.     put (&D[reg], dest - source, size);
  267.     result = D[reg] & size;
  268.     }
  269.  
  270. cc_update (GEN, GEN, GEN, CASE_2, CASE_6, source, dest, result, size, 0);
  271.  
  272. if (inst & 0x0100) {
  273.     inc_cyc ( (size == LONG) ? 12 : 8);
  274.     }
  275. else {
  276.     if (size == LONG) {
  277.         if ( (!(inst & 0x0030)) || ((inst & 0x003f) == 0x003c) )
  278.             inc_cyc (8);
  279.         else
  280.             inc_cyc (6);
  281.         }
  282.     else {
  283.         inc_cyc (4);
  284.         }
  285.     }
  286.  
  287. return SUCCESS;
  288.  
  289. }
  290.  
  291.  
  292. int    SUBA()
  293. {
  294. long    size;
  295. int    reg;
  296.  
  297. if (inst & 0x0100)
  298.     size = LONG;
  299. else
  300.     size = WORD;
  301.  
  302. if (eff_addr (size, ALL_ADDR, TRUE))
  303.     return (BAD_INST);            /* bad instruction format */
  304.  
  305. reg = (inst >> 9) & 0x0007;
  306.  
  307. source = EV1;
  308. dest = A[a_reg(reg)];
  309.  
  310. put (&A[a_reg(reg)], dest - source, size);
  311.  
  312. if (size == LONG) {
  313.     if ( (!(inst & 0x0030)) || ((inst & 0x003f) == 0x003c) )
  314.         inc_cyc (8);
  315.     else
  316.         inc_cyc (6);
  317.     }
  318. else 
  319.     inc_cyc (8);
  320.  
  321. return SUCCESS;
  322.  
  323. }
  324.  
  325.  
  326. int    SUBI()
  327. {
  328. long    size;
  329.  
  330. if (decode_size(&size))
  331.     return (BAD_INST);            /* bad instruction format */
  332.  
  333. mem_request (&PC, size, &source);
  334.  
  335. if (eff_addr (size, DATA_ALT_ADDR, TRUE))
  336.     return (BAD_INST);            /* bad instruction format */
  337.  
  338. dest = EV1;
  339.  
  340. put (EA1, dest - source, size);
  341. value_of (EA1, &result, size);
  342.  
  343. cc_update (GEN, GEN, GEN, CASE_2, CASE_6, source, dest, result, size, 0);
  344.  
  345. if (inst & 0x0038) {
  346.     inc_cyc ( (size == LONG) ? 20 : 12);
  347.     }
  348. else {
  349.     inc_cyc ( (size == LONG) ? 16 : 8);
  350.     }
  351.  
  352. return SUCCESS;
  353.  
  354. }
  355.  
  356.  
  357.  
  358. int    SUBQ()
  359. {
  360. long    size;
  361.  
  362. if (decode_size(&size))
  363.     return (BAD_INST);            /* bad size format */
  364.  
  365. if ((inst & 0x38) == 0x8)        /* if address reg direct, operation is long */
  366.     size = LONG;
  367.  
  368. if (eff_addr (size, ALTERABLE_ADDR, TRUE))
  369.     return (BAD_INST);            /* bad effectove address format */
  370.  
  371. source = ((inst >> 9) & 0x07);
  372. if (source == 0)             /* if source is '0', that corresponds to '8' */
  373.     source = 8;
  374.  
  375. dest = EV1;
  376.  
  377. put (EA1, dest - source, size);
  378. value_of (EA1, &result, size);
  379.  
  380. if (!((inst & 0x38) == 0x8))   /* if address reg direct, cc's not affected */
  381. cc_update (GEN, GEN, GEN, CASE_2, CASE_6, source, dest, result, size, 0);
  382.  
  383. switch (inst & 0x0038) {
  384.     case 0x0  : inc_cyc ( (size == LONG) ? 8 : 4);
  385.                 break;
  386.     case 0x1  : inc_cyc (8);
  387.                 break;
  388.     default   : inc_cyc ( (size == LONG) ? 12 : 8);
  389.                 break;
  390.     }
  391.  
  392. return SUCCESS;
  393.  
  394. }
  395.  
  396.  
  397.  
  398.  
  399. int    SUBX()
  400. {
  401. long    size;
  402. int    Rx, Ry;
  403.  
  404. if (decode_size(&size)) 
  405.     return (BAD_INST);
  406.  
  407. Ry = (inst >> 9) & 0x0007;
  408. Rx = inst & 0x0007;
  409.  
  410. /* perform the SUBX operation */
  411. if (inst & 0x0008)
  412.     {
  413.     Rx = a_reg(Rx);
  414.     Ry = a_reg(Ry);
  415.     if (size == LONG)
  416.         {
  417.         A[Rx] -= 4;
  418.         A[Ry] -= 4;
  419.         }
  420.     else if (size == WORD)
  421.         {
  422.         A[Rx] -= 2;
  423.         A[Ry] -= 2;
  424.         }
  425.     else
  426.         {
  427.         A[Rx]--;
  428.         A[Ry]--;
  429.         }
  430.     mem_req ( (int) A[Rx], size, &source);
  431.     mem_req ( (int) A[Ry], size, &dest);
  432.     put (&memory[A[Ry]], dest - source - ((SR & xbit)>> 4), size);
  433.     mem_req ( (int) A[Ry], size, &result);
  434.     }
  435. else
  436.     {
  437.     source = D[Rx] & size;
  438.     dest = D[Ry] & size;
  439.     put (&D[Ry], dest - source - ((SR & xbit) >> 4), size);
  440.     result = D[Ry] & size;
  441.     }
  442.  
  443. cc_update (GEN, GEN, CASE_1, CASE_2, CASE_6, source, dest, result, size, 0);
  444.  
  445. if (size == LONG)
  446.    inc_cyc ( (inst & 0x0008) ? 30 : 8);
  447. else
  448.    inc_cyc ( (inst & 0x0008) ? 18 : 4);
  449.  
  450. return SUCCESS;
  451.  
  452. }
  453.  
  454.