home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / compress / filearchivers / zip / zip-1.00.lha / operand.c < prev    next >
C/C++ Source or Header  |  1992-10-09  |  5KB  |  223 lines

  1. /*
  2.  * operand.c
  3.  *
  4.  * Operand manipulation routines
  5.  *
  6.  * Mark Howell 28-Jul-1992 V1.0
  7.  *
  8.  */
  9.  
  10. #include "ztypes.h"
  11.  
  12. /*
  13.  * load_operand
  14.  *
  15.  * Load an operand, either: a variable, popped from the stack or a literal.
  16.  *
  17.  */
  18.  
  19. #ifdef __STDC__
  20. zword_t load_operand (int type)
  21. #else
  22. zword_t load_operand (type)
  23. int type;
  24. #endif
  25. {
  26.     zword_t operand;
  27.  
  28.     if (type) {
  29.  
  30.         /* Type 1: byte literal, or type 2: operand specifier */
  31.  
  32.         operand = (zword_t) read_code_byte ();
  33.         if (type == 2) {
  34.  
  35.             /* If operand specifier non-zero then it's a variable, otherwise
  36.                it's the top of the stack */
  37.  
  38.             if (operand)
  39.                 operand = load_variable (operand);
  40.             else
  41.                 operand = stack[sp++];
  42.         }
  43.     } else
  44.  
  45.         /* Type 0: word literal */
  46.  
  47.         operand = read_code_word ();
  48.  
  49.     return (operand);
  50.  
  51. }/* load_operand */
  52.  
  53. /*
  54.  * store_operand
  55.  *
  56.  * Store an operand, either as a variable pushed on the stack.
  57.  *
  58.  */
  59.  
  60. #ifdef __STDC__
  61. void store_operand (zword_t operand)
  62. #else
  63. void store_operand (operand)
  64. zword_t operand;
  65. #endif
  66. {
  67.     zbyte_t specifier;
  68.  
  69.     /* Read operand specifier byte */
  70.  
  71.     specifier = read_code_byte ();
  72.  
  73.     /* If operand specifier non-zero then it's a variable, otherwise it's the
  74.        pushed on the stack */
  75.  
  76.     if (specifier)
  77.         store_variable (specifier, operand);
  78.     else
  79.         stack[--sp] = operand;
  80.  
  81. }/* store_operand */
  82.  
  83. /*
  84.  * load_variable
  85.  *
  86.  * Load a variable, either: a stack local variable, a global variable or the top
  87.  * of the stack.
  88.  *
  89.  */
  90.  
  91. #ifdef __STDC__
  92. zword_t load_variable (int number)
  93. #else
  94. zword_t load_variable (number)
  95. int number;
  96. #endif
  97. {
  98.     zword_t variable;
  99.  
  100.     if (number) {
  101.         if (number < 16)
  102.  
  103.             /* number in range 1 - 15, it's a stack local variable */
  104.  
  105.             variable = stack[fp - (number - 1)];
  106.         else
  107.  
  108.             /* number > 15, it's a global variable */
  109.  
  110.             variable = get_word (h_globals_offset + ((number - 16) * 2));
  111.     } else
  112.  
  113.         /* number = 0, get from top of stack */
  114.  
  115.         variable = stack[sp];
  116.  
  117.     return (variable);
  118.  
  119. }/* load_variable */
  120.  
  121. /*
  122.  * store_variable
  123.  *
  124.  * Store a variable, either: a stack local variable, a global variable or the top
  125.  * of the stack.
  126.  *
  127.  */
  128.  
  129. #ifdef __STDC__
  130. void store_variable (int number, zword_t variable)
  131. #else
  132. void store_variable (number, variable)
  133. int number;
  134. zword_t variable;
  135. #endif
  136. {
  137.  
  138.     if (number) {
  139.         if (number < 16)
  140.  
  141.             /* number in range 1 - 15, it's a stack local variable */
  142.  
  143.             stack[fp - (number - 1)] = variable;
  144.         else
  145.  
  146.             /* number > 15, it's a global variable */
  147.  
  148.             set_word (h_globals_offset + ((number - 16) * 2), variable);
  149.     } else
  150.  
  151.         /* number = 0, get from top of stack */
  152.  
  153.         stack[sp] = variable;
  154.  
  155. }/* store_variable */
  156.  
  157. /*
  158.  * conditional_jump
  159.  *
  160.  * Take a jump after an instruction based on the flag, either true or false. The
  161.  * jump can be modified by the change logic flag. Normally jumps are taken
  162.  * when the flag is true. When the change logic flag is set then the jump is
  163.  * taken when flag is false. A PC relative jump can also be taken. This jump can
  164.  * either be a positive or negative byte or word range jump. An additional
  165.  * feature is the return option. If the jump offset is zero or one then that
  166.  * literal value is passed to the return instruction, instead of a jump being
  167.  * taken. Complicated or what!
  168.  *
  169.  */
  170.  
  171. #ifdef __STDC__
  172. void conditional_jump (int flag)
  173. #else
  174. void conditional_jump (flag)
  175. int flag;
  176. #endif
  177. {
  178.     zbyte_t specifier;
  179.     zword_t offset;
  180.  
  181.     /* Read the specifier byte */
  182.  
  183.     specifier = read_code_byte ();
  184.  
  185.     /* If the reverse logic flag is set then reverse the flag */
  186.  
  187.     if (specifier & 0x80)
  188.         flag = (flag) ? 0 : 1;
  189.  
  190.     /* Jump offset is in bottom 6 bits */
  191.  
  192.     offset = (zword_t) specifier & 0x3f;
  193.  
  194.     /* If the byte range jump flag is not set then load another offset byte */
  195.  
  196.     if ((specifier & 0x40) == 0) {
  197.  
  198.         /* Add extra offset byte to existing shifted offset */
  199.  
  200.         offset = (offset << 8) + read_code_byte ();
  201.  
  202.         /* If top bit of offset is set then propogate the sign bit */
  203.  
  204.         if (offset & 0x2000)
  205.             offset |= 0xc000;
  206.     }
  207.  
  208.     /* If the flag is false then do the jump */
  209.  
  210.     if (flag == 0)
  211.  
  212.         /* If offset equals 0 or 1 return that value instead */
  213.  
  214.         if (offset == 0 || offset == 1)
  215.             ret (offset);
  216.         else
  217.  
  218.             /* Add offset to PC */
  219.  
  220.             pc = (unsigned long) (pc + (short) offset - 2);
  221.  
  222. }/* conditional_jump */
  223.