1 /* Nitfol - z-machine interpreter using Glk for output.
2 Copyright (C) 1999 Evin Robertson
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
18 The author can be reached at nitfol@deja.com
25 mop_store_result(get_var(operand[0]));
30 set_var(operand[0], operand[1]);
35 mop_store_result(ARITHMASK(operand[0] + operand[1]));
40 mop_store_result(ARITHMASK(operand[0] + neg(operand[1])));
46 mop_store_result(operand[0] & operand[1]);
51 mop_store_result(operand[0] | operand[1]);
56 mop_store_result(ARITHMASK(~operand[0]));
60 void op_art_shift(void)
62 if(is_neg(operand[1])) {
63 if(is_neg(operand[0])) {
65 zword foo = operand[0];
66 /* FIXME: is there a better way? */
67 for(i = 0; i < neg(operand[1]); i++) {
69 foo |= ZWORD_TOPBITMASK;
71 mop_store_result(foo);
73 mop_store_result(operand[0] >> neg(operand[1]));
76 mop_store_result(ARITHMASK(operand[0] << operand[1]));
80 void op_log_shift(void)
82 if(is_neg(operand[1]))
83 mop_store_result(operand[0] >> neg(operand[1]) );
85 mop_store_result(ARITHMASK(operand[0] << operand[1]));
91 zword val = ARITHMASK(get_var(operand[0]) - 1);
92 set_var(operand[0], val);
97 zword val = ARITHMASK(get_var(operand[0]) - 1);
98 set_var(operand[0], val);
100 if(is_lessthan(val, operand[1]))
108 zword val = ARITHMASK(get_var(operand[0]) + 1);
109 set_var(operand[0], val);
112 void op_inc_chk(void)
114 unsigned val = ARITHMASK(get_var(operand[0]) + 1);
115 set_var(operand[0], val);
117 if(is_greaterthan(val, operand[1]))
124 zword z_mult(zword a, zword b)
138 return ARITHMASK(neg(a * b));
140 return ARITHMASK(a * b);
145 zword z_div(zword a, zword b)
150 n_show_error(E_MATH, "division by zero", a);
170 zword z_mod(zword a, zword b)
175 n_show_error(E_MATH, "modulo by zero", a);
196 mop_store_result(z_div(operand[0], operand[1]));
202 mop_store_result(z_mod(operand[0], operand[1]));
208 mop_store_result(z_mult(operand[0], operand[1]));
212 /* FIXME: use our own rng */
213 zword z_random(zword num)
215 static BOOL rising = FALSE;
216 static unsigned r = 0;
220 if(faked_random_seed)
221 srand(faked_random_seed);
225 } else if(is_neg(num)) {
226 if(neg(num) < 1000) {
240 result = (1 + (rand() % num));
249 n_show_port(E_MATH, "some interpreters don't like @random 0", operand[0]);
251 mop_store_result(z_random(operand[0]));