

/*
 * math.c
 *
 * Arithmetic, compare and logical instructions
 *
 */

#include "ztypes.h"

/*
 * add
 *
 * Add two operands
 *
 */

#ifdef __STDC__
void add (zword_t a, zword_t b, z_globals *gl)
#else
void add (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a + b, gl);

}/* add */

/*
 * subtract
 *
 * Subtract two operands
 *
 */

#ifdef __STDC__
void subtract (zword_t a, zword_t b, z_globals *gl)
#else
void subtract (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a - b, gl);

}/* subtract */

/*
 * multiply
 *
 * Multiply two operands
 *
 */

#ifdef __STDC__
void multiply (zword_t a, zword_t b, z_globals *gl)
#else
void multiply (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a * b, gl);

}/* multiply */

/*
 * divide
 *
 * Divide two operands
 *
 */

#ifdef __STDC__
void divide (zword_t a, zword_t b, z_globals *gl)
#else
void divide (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a / b, gl);

}/* divide */

/*
 * remainder
 *
 * Modulus divide two operands
 *
 */

#ifdef __STDC__
void remainder (zword_t a, zword_t b, z_globals *gl)
#else
void remainder (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a % b, gl);

}/* remainder */

/*
 * shift
 *
 * Shift +/- n bits
 *
 */

#ifdef __STDC__
void shift (zword_t a, zword_t b, z_globals *gl)
#else
void shift (a, b, gl)
zword_t a;
zword_t b;
z_globals *gl;
#endif
{

    if ((short) b > 0)
        store_operand (a << (short) b, gl);
    else
        store_operand (a >> abs ((short) b), gl);

}/* shift */


/*
 * arith_shift
 *
 * Aritmetic shift +/- n bits
 *
 */

#ifdef __STDC__
void arith_shift (zword_t a, zword_t b, z_globals *gl)
#else
void arith_shift (a, b, gl)
zword_t a;
zword_t b;
z_globals *gl;
#endif
{

    if ((short) b > 0)
        store_operand (a << (short) b, gl);
    else
        if ((short) a > 0)
            store_operand (a >> abs ((short) b), gl);
        else
            store_operand (~((~a) >> abs ((short) b)), gl);

}/* arith_shift */

/*
 * or
 *
 * Logical OR
 *
 */

#ifdef __STDC__
void or (zword_t a, zword_t b, z_globals *gl)
#else
void or (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a | b, gl);

}/* or */

/*
 * not
 *
 * Logical NOT
 *
 */

#ifdef __STDC__
void not (zword_t a, z_globals *gl)
#else
void not (a, gl)
zword_t a;
z_globals *gl;
#endif
{

    store_operand (~a, gl);

}/* not */

/*
 * and
 *
 * Logical AND
 *
 */

#ifdef __STDC__
void and (zword_t a, zword_t b, z_globals *gl)
#else
void and (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    store_operand (a & b, gl);

}/* and */

/*
 * random
 *
 * Return random number between 1 and operand
 *
 */

#ifdef __STDC__
void zip_random (zword_t a, z_globals *gl)
#else
void zip_random (a, gl)
zword_t a;
z_globals *gl;
#endif
{

    if (a == 0)
        store_operand (0, gl);
    else if (a & 0x8000) { /* (a < 0) - used to set seed with #RANDOM */
        srand ((unsigned int) abs (a));
        store_operand (0, gl);
    } else /* (a > 0) */
        store_operand (((zword_t) rand () % a) + 1, gl);

}/* random */

/*
 * test
 *
 * Jump if operand 2 bit mask not set in operand 1
 *
 */

#ifdef __STDC__
void test (zword_t a, zword_t b, z_globals *gl)
#else
void test (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    conditional_jump (((~a) & b) == 0, gl);

}/* test */

/*
 * compare_zero
 *
 * Compare operand against zero
 *
 */

#ifdef __STDC__
void compare_zero (zword_t a, z_globals *gl)
#else
void compare_zero (a, gl)
zword_t a;
z_globals *gl;
#endif
{

    conditional_jump (a == 0, gl);

}/* compare_zero */

/*
 * compare_je
 *
 * Jump if operand 1 is equal to any other operand
 *
 */

#ifdef __STDC__
void compare_je (int count, zword_t *operand, z_globals *gl)
#else
void compare_je (count, operand, gl)
int count;
zword_t *operand;
z_globals *gl;
#endif
{
    int i;

    for (i = 1; i < count; i++)
        if (operand[0] == operand[i]) {
            conditional_jump (TRUE, gl);
            return;
        }
    conditional_jump (FALSE, gl);

}/* compare_je */

/*
 * compare_jl
 *
 * Jump if operand 1 is less than operand 2
 *
 */

#ifdef __STDC__
void compare_jl (zword_t a, zword_t b, z_globals *gl)
#else
void compare_jl (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    conditional_jump ((short) a < (short) b, gl);

}/* compare_jl */

/*
 * compare_jg
 *
 * Jump if operand 1 is greater than operand 2
 *
 */

#ifdef __STDC__
void compare_jg (zword_t a, zword_t b, z_globals *gl)
#else
void compare_jg (a, b, gl)
zword_t a, b;
z_globals *gl;
#endif
{

    conditional_jump ((short) a > (short) b, gl);

}/* compare_jg */



