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
27 while(!exit_decoder) {
28 zbyte opcode = HIBYTE(PC);
40 glk_tick(); /* tick tock hickery dock the mouse ran up the clock */
43 /* Top bits decide opcode/operand encoding */
45 case 0: case 1: /* long 2OP */
46 operand[0] = HIBYTE(PC); /* small constant */
47 operand[1] = HIBYTE(PC+1); /* small constant */
48 numoperands = 2; PC += 2;
49 opcode += OFFSET_2OP - 0x00;
53 case 2: case 3: /* long 2OP */
54 operand[0] = HIBYTE(PC); /* small constant */
55 operand[1] = get_var(HIBYTE(PC+1)); /* variable */
56 numoperands = 2; PC += 2;
57 opcode += OFFSET_2OP - 0x20;
61 case 4: case 5: /* long 2OP */
62 operand[0] = get_var(HIBYTE(PC)); /* variable */
63 operand[1] = HIBYTE(PC+1); /* small constant */
64 numoperands = 2; PC += 2;
65 opcode += OFFSET_2OP - 0x40;
69 case 6: case 7: /* long 2OP */
70 operand[0] = get_var(HIBYTE(PC)); /* variable */
71 operand[1] = get_var(HIBYTE(PC+1)); /* variable */
72 numoperands = 2; PC += 2;
73 opcode += OFFSET_2OP - 0x60;
77 case 8: /* short 1OP */
78 operand[0] = HIWORD(PC); /* large constant */
79 numoperands = 1; PC += ZWORD_SIZE;
80 opcode += OFFSET_1OP - 0x80;
84 case 9: /* short 1OP */
85 operand[0] = HIBYTE(PC); /* small constant */
86 numoperands = 1; PC += 1;
87 opcode += OFFSET_1OP - 0x90;
91 case 10: /* short 1OP */
92 operand[0] = get_var(HIBYTE(PC)); /* variable */
93 numoperands = 1; PC += 1;
94 opcode += OFFSET_1OP - 0xa0;
98 case 11: /* short 0OP */
101 opcode += OFFSET_0OP - 0xb0;
105 opcode = HIBYTE(PC); /* Get the extended opcode */
106 optypes = HIBYTE(PC+1);
110 if(OFFSET_EXT + opcode > OFFSET_END) {
111 n_show_error(E_INSTR, "unknown extended opcode", opcode);
116 for(numoperands = 0; numoperands < 4; numoperands++) {
117 switch(optypes & (3 << 6)) { /* Look at the highest two bits. */
119 operand[numoperands] = HIWORD(PC); PC+=ZWORD_SIZE; break;
121 operand[numoperands] = HIBYTE(PC); PC++; break;
123 operand[numoperands] = get_var(HIBYTE(PC)); PC++; break;
125 goto END_OF_EXTENDED; /* inky says, "use the goto." */
127 optypes <<= 2; /* Move the next two bits into position. */
130 opcode += OFFSET_EXT;
133 case 12: case 13: case 14: case 15: /* variable operand count */
135 optypes = ((unsigned) HIBYTE(PC)) << 8; /* Shift left so our loop will */
136 /* be the same for both 4 and 8 operands */
139 if(opcode == 0xec || opcode == 0xfa) { /* call_vs2 and call_vn2 */
141 optypes |= HIBYTE(PC); /* Fill the bottom 8 bits */
145 for(numoperands = 0; numoperands < maxoperands; numoperands++) {
146 switch(optypes & (3 << 14)) { /* Look at the highest two bits. */
148 operand[numoperands] = HIWORD(PC); PC+=ZWORD_SIZE; break;
150 operand[numoperands] = HIBYTE(PC); PC++; break;
152 operand[numoperands] = get_var(HIBYTE(PC)); PC++; break;
154 goto END_OF_VARIABLE;
156 optypes <<= 2; /* Move the next two bits into position. */
159 opcode += OFFSET_2OP - 0xc0;
162 opcodetable[opcode]();