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
22 void op_copy_table(void)
25 zword first = operand[0];
26 zword second = operand[1];
27 zword size = operand[2];
29 if(second == 0) { /* zero 'first' bytes */
30 for(i = 0; i < size; i++)
31 LOBYTEwrite(first + i, 0);
33 if(first > second || is_neg(size)) {
37 for(i = 0; i < size; i++) /* copy forward */
38 LOBYTEcopy(second + i, first + i);
41 for(i = 0; i < size; i++) /* copy backward */
42 LOBYTEcopy(second + size - i - 1, first + size - i - 1);
48 void op_scan_table(void)
51 int form = operand[3];
52 zword address = operand[1];
54 form = 0x82; /* default form - scan for words, increment by two bytes */
56 if(form & b10000000) { /* Bit 8 set means scan for words */
57 for(i = 0; i < operand[2]; i++) {
58 if(LOWORD(address) == operand[0]) {
59 mop_store_result(address);
63 address += form & b01111111; /* Bottom 7 bits give amount to increment */
67 } else { /* Bit 8 clear means scan for bytes */
68 for(i = 0; i < operand[2]; i++) {
69 if(LOBYTE(address) == operand[0]) {
70 mop_store_result(address);
74 address += form & b01111111;
83 mop_store_result(LOBYTE(operand[0] + operand[1]));
88 mop_store_result(LOWORD(operand[0] + operand[1] * ZWORD_SIZE));
91 static void z_write_header(zword i, zbyte val)
93 zbyte diff = LOBYTE(i) ^ val;
100 if(i != HD_FLAGS2 + 1) {
101 n_show_error(E_MEMORY, "attempt to write to non-dynamic byte in header", i);
104 if(diff > b00000111) {
105 n_show_error(E_MEMORY, "attempt to change non-dynamic bits in flags2", val);
109 if(diff & b00000001) {
110 if(val & b00000001) {
118 if(diff & b00000010) {
119 if(val & b00000010) {
129 zword addr = operand[0] + operand[1];
131 z_write_header(addr, (zbyte) operand[2]);
133 LOBYTEwrite(addr, operand[2]);
138 zword addr = operand[0] + operand[1] * ZWORD_SIZE;
140 z_write_header(addr, (zbyte) (operand[2] >> 8));
141 z_write_header(addr + 1, (zbyte) (operand[2] & 0xff));
143 LOWORDwrite(addr, operand[2]);
148 void header_extension_write(zword w, zword val)
154 if(LOWORD(z_headerext) < w)
157 LOWORDwrite(z_headerext + w, val);
160 zword header_extension_read(unsigned w)
166 if(LOWORD(z_headerext) < w)
169 return LOWORD(z_headerext + w);