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]();