~ubuntu-branches/ubuntu/karmic/xzip/karmic

« back to all changes in this revision

Viewing changes to interpre.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Schepler
  • Date: 2001-01-28 18:06:24 UTC
  • Revision ID: james.westby@ubuntu.com-20010128180624-hf85cm3jyb5df4cj
Tags: upstream-1.8.2
ImportĀ upstreamĀ versionĀ 1.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * interpre.c
 
3
 *
 
4
 * Main interpreter loop
 
5
 *
 
6
 */
 
7
 
 
8
#include "ztypes.h"
 
9
 
 
10
static int halt = FALSE;
 
11
 
 
12
/*
 
13
 * interpret
 
14
 *
 
15
 * Interpret Z code
 
16
 *
 
17
 */
 
18
 
 
19
#ifdef __STDC__
 
20
int interpret ()
 
21
#else
 
22
int interpret ()
 
23
#endif
 
24
{
 
25
    zbyte_t opcode;
 
26
    zword_t specifier, operand[8];
 
27
    int maxoperands, count, extended, i;
 
28
 
 
29
    interpreter_status = 1;
 
30
 
 
31
    /* Loop until HALT instruction executed */
 
32
 
 
33
    for (interpreter_state = RUN; interpreter_state == RUN && halt == FALSE; ) {
 
34
 
 
35
        /* Load opcode and set operand count */
 
36
 
 
37
        opcode = read_code_byte ();
 
38
        if (h_type > V4 && opcode == 0xbe) {
 
39
            opcode = read_code_byte ();
 
40
            extended = TRUE;
 
41
        } else
 
42
            extended = FALSE;
 
43
        count = 0;
 
44
 
 
45
        /* Multiple operand instructions */
 
46
 
 
47
        if ((opcode < 0x80 || opcode > 0xc0) || extended == TRUE) {
 
48
 
 
49
            /* Two operand class, load both operands */
 
50
 
 
51
            if (opcode < 0x80 && extended == FALSE) {
 
52
                operand[count++] = load_operand ((opcode & 0x40) ? 2 : 1);
 
53
                operand[count++] = load_operand ((opcode & 0x20) ? 2 : 1);
 
54
                opcode &= 0x1f;
 
55
            } else {
 
56
 
 
57
                /* Variable operand class, load operand specifier */
 
58
 
 
59
                opcode &= 0x3f;
 
60
                if (opcode == 0x2c || opcode == 0x3a) { /* Extended CALL instruction */
 
61
                    specifier = read_code_word ();
 
62
                    maxoperands = 8;
 
63
                } else {
 
64
                    specifier = read_code_byte ();
 
65
                    maxoperands = 4;
 
66
                }
 
67
 
 
68
                /* Load operands */
 
69
 
 
70
                for (i = (maxoperands - 1) * 2; i >= 0; i -= 2)
 
71
                    if (((specifier >> i) & 0x03) != 3)
 
72
                        operand[count++] = load_operand ((specifier >> i) & 0x03);
 
73
                    else
 
74
                        i = 0;
 
75
            }
 
76
 
 
77
            if (extended == TRUE)
 
78
                switch ((char) opcode) {
 
79
 
 
80
                    /* Extended operand instructions */
 
81
 
 
82
                    case 0x00: save (count, operand); break;
 
83
                    case 0x01: restore (count, operand); break;
 
84
                    case 0x02: shift (operand[0], operand[1]); break;
 
85
                    case 0x03: arith_shift (operand[0], operand[1]); break;
 
86
                    case 0x04: set_font_attribute (operand[0]); break;
 
87
 
 
88
                    case 0x09: undo_save (); break;
 
89
                    case 0x0a: undo_restore (); break;
 
90
 
 
91
                    default: fatal ("Illegal operation");
 
92
                }
 
93
            else
 
94
                switch ((char) opcode) {
 
95
 
 
96
                    /* Two or multiple operand instructions */
 
97
 
 
98
                    case 0x01: compare_je (count, operand); break;
 
99
                    case 0x02: compare_jl (operand[0], operand[1]); break;
 
100
                    case 0x03: compare_jg (operand[0], operand[1]); break;
 
101
                    case 0x04: decrement_check (operand[0], operand[1]); break;
 
102
                    case 0x05: increment_check (operand[0], operand[1]); break;
 
103
                    case 0x06: compare_parent_object (operand[0], operand[1]); break;
 
104
                    case 0x07: test (operand[0], operand[1]); break;
 
105
                    case 0x08: or (operand[0], operand[1]); break;
 
106
                    case 0x09: and (operand[0], operand[1]); break;
 
107
                    case 0x0a: test_attr (operand[0], operand[1]); break;
 
108
                    case 0x0b: set_attr (operand[0], operand[1]); break;
 
109
                    case 0x0c: clear_attr (operand[0], operand[1]); break;
 
110
                    case 0x0d: store_variable (operand[0], operand[1]); break;
 
111
                    case 0x0e: insert_object (operand[0], operand[1]); break;
 
112
                    case 0x0f: load_word (operand[0], operand[1]); break;
 
113
                    case 0x10: load_byte (operand[0], operand[1]); break;
 
114
                    case 0x11: load_property (operand[0], operand[1]); break;
 
115
                    case 0x12: load_property_address (operand[0], operand[1]); break;
 
116
                    case 0x13: load_next_property (operand[0], operand[1]); break;
 
117
                    case 0x14: add (operand[0], operand[1]); break;
 
118
                    case 0x15: subtract (operand[0], operand[1]); break;
 
119
                    case 0x16: multiply (operand[0], operand[1]); break;
 
120
                    case 0x17: divide (operand[0], operand[1]); break;
 
121
                    case 0x18: remainder (operand[0], operand[1]); break;
 
122
                    case 0x19: call (count, operand, FUNCTION); break;
 
123
                    case 0x1a: call (count, operand, PROCEDURE); break;
 
124
                    case 0x1b: set_colour_attribute (operand[0], operand[1]); break;
 
125
                    case 0x1c: unwind (operand[0], operand[1]); break;
 
126
 
 
127
                    /* Multiple operand instructions */
 
128
 
 
129
                    case 0x20: call (count, operand, FUNCTION); break;
 
130
                    case 0x21: store_word (operand[0], operand[1], operand[2]); break;
 
131
                    case 0x22: store_byte (operand[0], operand[1], operand[2]); break;
 
132
                    case 0x23: store_property (operand[0], operand[1], operand[2]); break;
 
133
                    case 0x24: read_line (count, operand); break;
 
134
                    case 0x25: print_character (operand[0]); break;
 
135
                    case 0x26: print_number (operand[0]); break;
 
136
                    case 0x27: ziprandom (operand[0]); break;
 
137
                    case 0x28: push_var (operand[0]); break;
 
138
                    case 0x29: pop_var (operand[0]); break;
 
139
                    case 0x2a: set_status_size (operand[0]); break;
 
140
                    case 0x2b: select_window (operand[0]); break;
 
141
                    case 0x2c: call (count, operand, FUNCTION); break;
 
142
                    case 0x2d: erase_window (operand[0]); break;
 
143
                    case 0x2e: erase_line (operand[0]); break;
 
144
                    case 0x2f: set_cursor_position (operand[0], operand[1]); break;
 
145
 
 
146
                    case 0x31: set_video_attribute (operand[0]); break;
 
147
                    case 0x32: set_format_mode (operand[0]); break;
 
148
                    case 0x33: set_print_modes (operand[0], operand[1]); break;
 
149
                    case 0x34: open_playback (operand[0]); break;
 
150
                    case 0x35: sound (count, operand); break;
 
151
                    case 0x36: read_character (count, operand); break;
 
152
                    case 0x37: scan_data (count, operand); break;
 
153
                    case 0x38: not (operand[0]); break;
 
154
                    case 0x39: call (count, operand, PROCEDURE); break;
 
155
                    case 0x3a: call (count, operand, PROCEDURE); break;
 
156
                    case 0x3b: tokenise (count, operand); break;
 
157
                    case 0x3c: encode (operand[0], operand[1], operand[2], operand[3]); break;
 
158
                    case 0x3d: move_data (operand[0], operand[1], operand[2]); break;
 
159
                    case 0x3e: print_window (count, operand); break;
 
160
                    case 0x3f: check_argument (operand[0]); break;
 
161
 
 
162
                    default: fatal ("Illegal operation");
 
163
                }
 
164
        } else {
 
165
 
 
166
            /* Single operand class, load operand and execute instruction */
 
167
 
 
168
            if (opcode < 0xb0) {
 
169
                operand[0] = load_operand ((opcode >> 4) & 0x03);
 
170
                switch ((char) opcode & 0x0f) {
 
171
                    case 0x00: compare_zero (operand[0]); break;
 
172
                    case 0x01: load_next_object (operand[0]); break;
 
173
                    case 0x02: load_child_object (operand[0]); break;
 
174
                    case 0x03: load_parent_object (operand[0]); break;
 
175
                    case 0x04: load_property_length (operand[0]); break;
 
176
                    case 0x05: increment (operand[0]); break;
 
177
                    case 0x06: decrement (operand[0]); break;
 
178
                    case 0x07: print_offset (operand[0]); break;
 
179
                    case 0x08: call (1, operand, FUNCTION); break;
 
180
                    case 0x09: remove_object (operand[0]); break;
 
181
                    case 0x0a: print_object (operand[0]); break;
 
182
                    case 0x0b: ret (operand[0]); break;
 
183
                    case 0x0c: jump (operand[0]); break;
 
184
                    case 0x0d: print_address (operand[0]); break;
 
185
                    case 0x0e: load (operand[0]); break;
 
186
                    case 0x0f:
 
187
                        if (h_type > V4)
 
188
                            call (1, operand, PROCEDURE);
 
189
                        else
 
190
                            not (operand[0]);
 
191
                        break;
 
192
                }
 
193
            } else {
 
194
 
 
195
                /* Zero operand class, execute instruction */
 
196
 
 
197
                switch ((char) opcode & 0x0f) {
 
198
                    case 0x00: ret (TRUE); break;
 
199
                    case 0x01: ret (FALSE); break;
 
200
                    case 0x02: print_literal (); break;
 
201
                    case 0x03: println_return (); break;
 
202
 
 
203
                    case 0x05: save (count, operand); break;
 
204
                    case 0x06: restore (count, operand); break;
 
205
                    case 0x07: restart (); break;
 
206
                    case 0x08: ret (stack[sp++]); break;
 
207
                    case 0x09: get_fp (); break;
 
208
                    case 0x0a: halt = TRUE; break;
 
209
                    case 0x0b: new_line (); break;
 
210
                    case 0x0c: display_status_line (); break;
 
211
                    case 0x0d: verify (); break;
 
212
 
 
213
                    case 0x0f: conditional_jump (TRUE); break;
 
214
 
 
215
                    default: fatal ("Illegal operation");
 
216
                }
 
217
            }
 
218
        }
 
219
    }
 
220
 
 
221
    return (interpreter_status);
 
222
 
 
223
}/* interpret */