X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Ffrotz%2Fvariable.c;fp=interpreters%2Ffrotz%2Fvariable.c;h=3e5c6e0c0980cfb6e39d133093f1a0a057257f43;hb=b1f1dc50b22b30c4d7176e1ff7c0805e80fe0724;hp=0000000000000000000000000000000000000000;hpb=50176172d18ae72d019181725c5629d45d21c548;p=projects%2Fchimara%2Fchimara.git diff --git a/interpreters/frotz/variable.c b/interpreters/frotz/variable.c new file mode 100644 index 0000000..3e5c6e0 --- /dev/null +++ b/interpreters/frotz/variable.c @@ -0,0 +1,304 @@ +/* variable.c - Variable and stack related opcodes + * Copyright (c) 1995-1997 Stefan Jokisch + * + * This file is part of Frotz. + * + * Frotz is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Frotz is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include "frotz.h" + +/* + * z_dec, decrement a variable. + * + * zargs[0] = variable to decrement + * + */ + +void z_dec (void) +{ + zword value; + + if (zargs[0] == 0) + (*sp)--; + else if (zargs[0] < 16) + (*(fp - zargs[0]))--; + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + LOW_WORD (addr, value) + value--; + SET_WORD (addr, value) + } + +}/* z_dec */ + +/* + * z_dec_chk, decrement a variable and branch if now less than value. + * + * zargs[0] = variable to decrement + * zargs[1] = value to check variable against + * + */ + +void z_dec_chk (void) +{ + zword value; + + if (zargs[0] == 0) + value = --(*sp); + else if (zargs[0] < 16) + value = --(*(fp - zargs[0])); + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + LOW_WORD (addr, value) + value--; + SET_WORD (addr, value) + } + + branch ((short) value < (short) zargs[1]); + +}/* z_dec_chk */ + +/* + * z_inc, increment a variable. + * + * zargs[0] = variable to increment + * + */ + +void z_inc (void) +{ + zword value; + + if (zargs[0] == 0) + (*sp)++; + else if (zargs[0] < 16) + (*(fp - zargs[0]))++; + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + LOW_WORD (addr, value) + value++; + SET_WORD (addr, value) + } + +}/* z_inc */ + +/* + * z_inc_chk, increment a variable and branch if now greater than value. + * + * zargs[0] = variable to increment + * zargs[1] = value to check variable against + * + */ + +void z_inc_chk (void) +{ + zword value; + + if (zargs[0] == 0) + value = ++(*sp); + else if (zargs[0] < 16) + value = ++(*(fp - zargs[0])); + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + LOW_WORD (addr, value) + value++; + SET_WORD (addr, value) + } + + branch ((short) value > (short) zargs[1]); + +}/* z_inc_chk */ + +/* + * z_load, store the value of a variable. + * + * zargs[0] = variable to store + * + */ + +void z_load (void) +{ + zword value; + + if (zargs[0] == 0) + value = *sp; + else if (zargs[0] < 16) + value = *(fp - zargs[0]); + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + LOW_WORD (addr, value) + } + + store (value); + +}/* z_load */ + +/* + * z_pop, pop a value off the game stack and discard it. + * + * no zargs used + * + */ + +void z_pop (void) +{ + + sp++; + +}/* z_pop */ + +/* + * z_pop_stack, pop n values off the game or user stack and discard them. + * + * zargs[0] = number of values to discard + * zargs[1] = address of user stack (optional) + * + */ + +void z_pop_stack (void) +{ + + if (zargc == 2) { /* it's a user stack */ + + zword size; + zword addr = zargs[1]; + + LOW_WORD (addr, size) + + size += zargs[0]; + storew (addr, size); + + } else sp += zargs[0]; /* it's the game stack */ + +}/* z_pop_stack */ + +/* + * z_pull, pop a value off... + * + * a) ...the game or a user stack and store it (V6) + * + * zargs[0] = address of user stack (optional) + * + * b) ...the game stack and write it to a variable (other than V6) + * + * zargs[0] = variable to write value to + * + */ + +void z_pull (void) +{ + zword value; + + if (h_version != V6) { /* not a V6 game, pop stack and write */ + + value = *sp++; + + if (zargs[0] == 0) + *sp = value; + else if (zargs[0] < 16) + *(fp - zargs[0]) = value; + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + SET_WORD (addr, value) + } + + } else { /* it's V6, but is there a user stack? */ + + if (zargc == 1) { /* it's a user stack */ + + zword size; + zword addr = zargs[0]; + + LOW_WORD (addr, size) + + size++; + storew (addr, size); + + addr += 2 * size; + LOW_WORD (addr, value) + + } else value = *sp++; /* it's the game stack */ + + store (value); + + } + +}/* z_pull */ + +/* + * z_push, push a value onto the game stack. + * + * zargs[0] = value to push onto the stack + * + */ + +void z_push (void) +{ + + *--sp = zargs[0]; + +}/* z_push */ + +/* + * z_push_stack, push a value onto a user stack then branch if successful. + * + * zargs[0] = value to push onto the stack + * zargs[1] = address of user stack + * + */ + +void z_push_stack (void) +{ + zword size; + zword addr = zargs[1]; + + LOW_WORD (addr, size) + + if (size != 0) { + + storew ((zword) (addr + 2 * size), zargs[0]); + + size--; + storew (addr, size); + + } + + branch (size); + +}/* z_push_stack */ + +/* + * z_store, write a value to a variable. + * + * zargs[0] = variable to be written to + * zargs[1] = value to write + * + */ + +void z_store (void) +{ + zword value = zargs[1]; + + if (zargs[0] == 0) + *sp = value; + else if (zargs[0] < 16) + *(fp - zargs[0]) = value; + else { + zword addr = h_globals + 2 * (zargs[0] - 16); + SET_WORD (addr, value) + } + +}/* z_store */