1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GLK_FROTZ_PROCESSOR
24 #define GLK_FROTZ_PROCESSOR
25 
26 #include "glk/frotz/mem.h"
27 #include "glk/frotz/glk_interface.h"
28 #include "glk/frotz/frotz_types.h"
29 #include "common/stack.h"
30 
31 namespace Glk {
32 namespace Frotz {
33 
34 #define TEXT_BUFFER_SIZE 200
35 
36 #define CODE_BYTE(v)	   v = codeByte()
37 #define CODE_WORD(v)       v = codeWord()
38 #define CODE_IDX_WORD(v,i) v = codeWordIdx(i)
39 #define GET_PC(v)          v = getPC()
40 #define SET_PC(v)          setPC(v)
41 
42 enum string_type {
43 	LOW_STRING, ABBREVIATION, HIGH_STRING, EMBEDDED_STRING, VOCABULARY
44 };
45 
46 class Processor;
47 class Quetzal;
48 typedef void (Processor::*Opcode)();
49 
50 /**
51  * Zcode processor
52  */
53 class Processor : public GlkInterface, public virtual Mem {
54 	friend class Quetzal;
55 private:
56 	static const char *const ERR_MESSAGES[ERR_NUM_ERRORS];
57 	static Opcode var_opcodes[64];
58 	static Opcode ext_opcodes[64];
59 	Common::Array<Opcode> op0_opcodes;
60 	Common::Array<Opcode> op1_opcodes;
61 
62 	int _finished;
63 	zword zargs[8];
64 	int zargc;
65 	uint _randomInterval;
66 	uint _randomCtr;
67 	bool first_restart;
68 	bool script_valid;
69 
70 	// Stack data
71 	zword _stack[STACK_SIZE];
72 	zword *_sp;
73 	zword *_fp;
74 	zword _frameCount;
75 
76 	// Text related fields
77 	static zchar ZSCII_TO_LATIN1[];
78 	zchar *_decoded, *_encoded;
79 	int _resolution;
80 	int _errorCount[ERR_NUM_ERRORS];
81 
82 	// Buffer related fields
83 	bool _locked;
84 	zchar _prevC;
85 	zchar _buffer[TEXT_BUFFER_SIZE];
86 	size_t _bufPos;
87 
88 	// Stream related fields
89 	int script_width;
90 	strid_t sfp, rfp, pfp;
91 	bool ostream_screen;
92 	bool ostream_script;
93 	bool ostream_memory;
94 	bool ostream_record;
95 	bool istream_replay;
96 	bool message;
97 	Common::FixedStack<Redirect, MAX_NESTING> _redirect;
98 protected:
99 	/**
100 	 * \defgroup General support methods
101 	 * @{
102 	 */
103 
104 	/**
105 	 * Load an operand, either a variable or a constant.
106 	 */
107 	void load_operand(zbyte type);
108 
109 	/**
110 	 * Given the operand specifier byte, load all (up to four) operands
111 	 * for a VAR or EXT opcode.
112 	 */
113 	void load_all_operands(zbyte specifier);
114 
115 	/**
116 	 * Call a subroutine. Save PC and FP then load new PC and initialise
117 	 * new stack frame. Note that the caller may legally provide less or
118 	 * more arguments than the function actually has. The call type "ct"
119 	 * can be 0 (z_call_s), 1 (z_call_n) or 2 (direct call).
120 	 */
121 	void call(zword routine, int argc, zword *args, int ct);
122 
123 	/**
124 	 * Return from the current subroutine and restore the previous _stack
125 	 * frame. The result may be stored (0), thrown away (1) or pushed on
126 	 * the stack (2). In the latter case a direct call has been finished
127 	 * and we must exit the interpreter loop.
128 	 */
129 	void ret(zword value);
130 
131 	/**
132 	 * Take a jump after an instruction based on the flag, either true or
133 	 * false. The branch can be short or long; it is encoded in one or two
134 	 * bytes respectively. When bit 7 of the first byte is set, the jump
135 	 * takes place if the flag is true; otherwise it is taken if the flag
136 	 * is false. When bit 6 of the first byte is set, the branch is short;
137 	 * otherwise it is long. The offset occupies the bottom 6 bits of the
138 	 * first byte plus all the bits in the second byte for long branches.
139 	 * Uniquely, an offset of 0 means return false, and an offset of 1 is
140 	 * return true.
141 	 */
142 	void branch(bool flag);
143 
144 	/**
145 	 * Store an operand, either as a variable or pushed on the stack.
146 	 */
147 	void store(zword value);
148 
149 	/*
150 	 * Call the interpreter loop directly. This is necessary when
151 	 *
152 	 * - a sound effect has been finished
153 	 * - a read instruction has timed out
154 	 * - a newline countdown has hit zero
155 	 *
156 	 * The interpreter returns the result value on the stack.
157 	 */
158 	int direct_call(zword addr);
159 
160 	/**
161 	 * Set the seed value for the random number generator.
162 	 */
163 	void seed_random(int value);
164 
165 	/**@}*/
166 
167 	/**
168 	 * \defgroup Input support methods
169 	 * @{
170 	 */
171 
172 	 /**
173 	  * High level output function.
174 	  */
175 	void print_char(zchar c);
176 
177 	/**
178 	 * Print a string of ASCII characters.
179 	 */
180 	void print_string(const char *s);
181 
182 	/**
183 	 * Print an unsigned 32bit number in decimal or hex.
184 	 */
185 	void print_long(uint value, int base);
186 
187 	 /**
188 	  * High level newline function.
189 	  */
190 	void new_line();
191 
192 	/**
193 	 * Copy the contents of the text buffer to the output streams.
194 	 */
195 	void flush_buffer();
196 
197 	/**
198 	 * Returns true if the buffer is empty
199 	 */
bufferEmpty()200 	bool bufferEmpty() const { return !_bufPos; }
201 
202 	/**
203 	 * An error has occurred. Ignore it, pass it to os_fatal or report
204 	 * it according to err_report_mode.
205 	 * @param errNum		Numeric code for error (1 to ERR_NUM_ERRORS)
206 	 */
207 	void runtimeError(ErrorCode errNum);
208 
209 	/**@}*/
210 
211 	/**
212 	 * \defgroup Input support methods
213 	 * @{
214 	 */
215 
216 	/**
217 	 * Check if the given key is an input terminator.
218 	 */
219 	bool is_terminator(zchar key);
220 
221 	/**
222 	 * Ask the user a question; return true if the answer is yes.
223 	 */
224 	bool read_yes_or_no(const char *s);
225 
226 	/**
227 	 * Read a string from the current input stream.
228 	 */
229 	void read_string(int max, zchar *buffer);
230 
231 	/**
232 	 * Ask the user to type in a number and return it.
233 	 */
234 	int read_number();
235 
236 	/**@}*/
237 
238 	/**
239 	 * \defgroup Memory support methods
240 	 * @{
241 	 */
242 
243 	/**
244 	 * Called when the H_FLAGS field of the header has changed
245 	 */
246 	virtual void flagsChanged(zbyte value) override;
247 
248 	/**
249 	 * This function does the dirty work for z_save_undo.
250 	 */
251 	int save_undo();
252 
253 	/**
254 	 * This function does the dirty work for z_restore_undo.
255 	 */
256 	int restore_undo();
257 
258 	/**
259 	 * Begin output redirection to the memory of the Z-machine.
260 	 */
261 	void memory_open(zword table, zword xsize, bool buffering);
262 
263 	/**
264 	 * End of output redirection.
265 	 */
266 	void memory_close();
267 
268 	/**
269 	 * Redirect a newline to the memory of the Z-machine.
270 	 */
271 	void memory_new_line();
272 
273 	/**
274 	 * Redirect a string of characters to the memory of the Z-machine.
275 	 */
276 	void memory_word(const zchar *s);
277 
278 	/**@}*/
279 
280 	/**
281 	 * \defgroup Object support methods
282 	 * @{
283 	 */
284 
285 	/**
286 	 * Calculate the address of an object.
287 	 */
288 	zword object_address(zword obj);
289 
290 	/**
291 	 * Return the address of the given object's name.
292 	 */
293 	zword object_name(zword object);
294 
295 	/**
296 	 * Calculate the start address of the property list associated with an object.
297 	 */
298 	zword first_property(zword obj);
299 
300 	/**
301 	 * Calculate the address of the next property in a property list.
302 	 */
303 	zword next_property(zword prop_addr);
304 
305 	/**
306 	 * Unlink an object from its parent and siblings.
307 	 */
308 	void unlink_object(zword object);
309 
310 	/**@}*/
311 
312 	/**
313 	 * \defgroup Screen support methods
314 	 * @{
315 	 */
316 
317 	/**
318 	 * Start printing a so-called debugging message. The contents of the
319 	 * message are passed to the message stream, a Frotz specific output
320 	 * stream with maximum priority.
321 	 */
322 	void screen_mssg_on();
323 
324 	/**
325 	 * Stop printing a "debugging" message
326 	 */
327 	void screen_mssg_off();
328 
329 	/**
330 	 * Map a runic character to its Unicode equivalent, if there is one
331 	 */
332 	uint32 zchar_to_unicode_rune(zchar c);
333 
334 	/**
335 	 * Display a single character on the screen.
336 	 */
337 	void screen_char(zchar c);
338 
339 	/**
340 	 * Print a newline to the screen.
341 	 */
342 	void screen_new_line();
343 
344 	/**
345 	 * Print a newline to the screen.
346 	 */
347 	void screen_word(const zchar *s);
348 
349 	/**
350 	 * Erase the entire screen to background colour.
351 	 */
352 	void erase_screen(zword win);
353 
354 	/**
355 	 * Erase a window to background colour.
356 	 */
357 	void erase_window(zword win);
358 
359 	/**@}*/
360 
361 	/**
362 	 * \defgroup Stream support methods
363 	 * @{
364 	 */
365 
366 	/**
367 	 * Waits for the user to type an input line
368 	 */
369 	zchar console_read_input(int max, zchar *buf, zword timeout, bool continued);
370 
371 	/**
372 	 * Waits for a keypress
373 	 */
374 	zchar console_read_key(zword timeout);
375 
376 	/**
377 	 * Write a single character to the scrollback buffer.
378 	 *
379 	 */
380 	void scrollback_char(zchar c);
381 
382 	/**
383 	 * Write a string to the scrollback buffer.
384 	 */
385 	void scrollback_word(const zchar *s);
386 
387 	/**
388 	 * Send an input line to the scrollback buffer.
389 	 */
390 	void scrollback_write_input(const zchar *buf, zchar key);
391 
392 	/**
393 	 * Remove an input line from the scrollback buffer.
394 	 */
395 	void scrollback_erase_input(const zchar *buf);
396 
397 	/**
398 	 * Start printing a "debugging" message.
399 	 */
400 	void stream_mssg_on();
401 
402 	/**
403 	 * Stop printing a "debugging" message.
404 	 */
405 	void stream_mssg_off();
406 
407 	/**
408 	 * Send a single character to the output stream.
409 	 */
410 	void stream_char(zchar c);
411 
412 	/**
413 	 * Send a string of characters to the output streams.
414 	 */
415 	void stream_word(const zchar *s);
416 
417 	/**
418 	 * Send a newline to the output streams.
419 	 */
420 	void stream_new_line();
421 
422 	/**
423 	 * Read a single keystroke from the current input stream.
424 	 */
425 	zchar stream_read_key(zword timeout, zword routine, bool hot_keys);
426 
427 	/**
428 	 * Read a line of input from the current input stream.
429 	 */
430 	zchar stream_read_input(int max, zchar *buf, zword timeout, zword routine,
431 		bool hot_keys, bool no_scripting);
432 
433 	/*
434 	 * script_open
435 	 *
436 	 * Open the transscript file. 'AMFV' makes this more complicated as it
437 	 * turns transscription on/off several times to exclude some text from
438 	 * the transscription file. This wasn't a problem for the original V4
439 	 * interpreters which always sent transscription to the printer, but it
440 	 * means a problem to modern interpreters that offer to open a new file
441 	 * every time transscription is turned on. Our solution is to append to
442 	 * the old transscription file in V1 to V4, and to ask for a new file
443 	 * name in V5+.
444 	 *
445 	 */
446 	void script_open();
447 
448 	/*
449 	 * Stop transscription.
450 	 */
451 	void script_close();
452 
453 	/**
454 	 * Write a newline to the transscript file.
455 	 */
456 	void script_new_line();
457 
458 	/**
459 	 * Write a single character to the transscript file.
460 	 */
461 	void script_char(zchar c);
462 
463 	/**
464 	 * Write a string to the transscript file.
465 	 */
466 	void script_word(const zchar *s);
467 
468 	/**
469 	 * Send an input line to the transscript file.
470 	 */
471 	void script_write_input(const zchar *buf, zchar key);
472 
473 	/**
474 	 * Remove an input line from the transscript file.
475 	 */
476 	void script_erase_input(const zchar *buf);
477 
478 	/**
479 	 * Start sending a "debugging" message to the transscript file.
480 	 */
481 	void script_mssg_on();
482 
483 	/**
484 	 * Stop writing a "debugging" message.
485 	 */
486 	void script_mssg_off();
487 
488 	/**
489 	 * Open a file to record the player's input.
490 	 */
491 	void record_open();
492 
493 	/**
494 	 * Stop recording the player's input.
495 	 */
496 	void record_close();
497 
498 	/**
499 	 * Helper function for record_char.
500 	 */
501 	void record_code(int c, bool force_encoding);
502 
503 	/**
504 	 * Write a character to the command file.
505 	 */
506 	void record_char(zchar c);
507 
508 	/**
509 	 * Copy a keystroke to the command file.
510 	 */
511 	void record_write_key(zchar key);
512 
513 	/**
514 	 * Copy a line of input to a command file.
515 	 */
516 	void record_write_input(const zchar *buf, zchar key);
517 
518 	/**
519 	 * Open a file of commands for playback.
520 	 */
521 	void replay_open();
522 
523 	/**
524 	 * Stop playback of commands.
525 	 */
526 	void replay_close();
527 
528 	/*
529 	 * Helper function for replay_key and replay_line.
530 	 */
531 	int replay_code();
532 
533 	/**
534 	 * Read a character from the command file.
535 	 */
536 	zchar replay_char();
537 
538 	/**
539 	 * Read a keystroke from a command file.
540 	 */
541 	zchar replay_read_key();
542 
543 	/*
544 	 * Read a line of input from a command file.
545 	 */
546 	zchar replay_read_input(zchar *buf);
547 
548 	/**@}*/
549 
550 	/**
551 	 * \defgroup Text support methods
552 	 * @{
553 	 */
554 
555 	/**
556 	 * Map a ZSCII character into Unicode.
557 	 */
558 	zchar translate_from_zscii(zbyte c);
559 
560 	/**
561 	 * Convert a Unicode character to ZSCII, returning 0 on failure.
562 	 */
563 	zbyte unicode_to_zscii(zchar c);
564 
565 	/**
566 	 * Map a Unicode character onto the ZSCII alphabet.
567 	 */
568 	zbyte translate_to_zscii(zchar c);
569 
570 	/**
571 	 * Return a character from one of the three character sets.
572 	 */
573 	zchar alphabet(int set, int index);
574 
575 	/**
576 	 * Find the number of bytes used for dictionary resolution.
577 	 */
578 	void find_resolution();
579 
580 	/**
581 	 * Copy a ZSCII string from the memory to the global "decoded" string.
582 	 */
583 	void load_string(zword addr, zword length);
584 
585 	/**
586 	 * Encode the Unicode text in the global "decoded" string then write
587 	 * the result to the global "encoded" array. (This is used to look up
588 	 * words in the dictionary.) Up to V3 the vocabulary resolution is
589 	 * two, from V4 it is three, and from V9 it is any number of words.
590 	 * Because each word contains three Z-characters, that makes six or
591 	 * nine Z-characters respectively. Longer words are chopped to the
592 	 * proper size, shorter words are are padded out with 5's. For word
593 	 * completion we pad with 0s and 31s, the minimum and maximum
594 	 * Z-characters.
595 	 */
596 	void encode_text(int padding);
597 
598 	/**
599 	 * Convert _encoded text to Unicode. The _encoded text consists of 16bit
600 	 * words. Every word holds 3 Z-characters (5 bits each) plus a spare
601 	 * bit to mark the last word. The Z-characters translate to ZSCII by
602 	 * looking at the current current character set. Some select another
603 	 * character set, others refer to abbreviations.
604 	 *
605 	 * There are several different string types:
606 	 *
607 	 *    LOW_STRING - from the lower 64KB (byte address)
608 	 *    ABBREVIATION - from the abbreviations table (word address)
609 	 *    HIGH_STRING - from the end of the memory map (packed address)
610 	 *    EMBEDDED_STRING - from the instruction stream (at PC)
611 	 *    VOCABULARY - from the dictionary (byte address)
612 	 *
613 	 * The last type is only used for word completion.
614 	 */
615 	void decode_text(string_type st, zword addr);
616 
617 	/**
618 	 * Print a signed 16bit number.
619 	 */
620 	void print_num(zword value);
621 
622 	/**
623 	 * print_object
624 	 *
625 	 * Print an object description.
626 	 *
627 	 */
628 	void print_object(zword object);
629 
630 	/**
631 	 * Scan a dictionary searching for the given word. The first argument
632 	 * can be
633 	 *
634 	 * 0x00 - find the first word which is >= the given one
635 	 * 0x05 - find the word which exactly matches the given one
636 	 * 0x1f - find the last word which is <= the given one
637 	 *
638 	 * The return value is 0 if the search fails.
639 	 */
640 	zword lookup_text(int padding, zword dct);
641 
642 	/**
643 	 * Handles converting abbreviations that weren't handled by early Infocom games
644 	 * into their expanded versions
645 	 */
646 	void handleAbbreviations();
647 
648 	/**
649 	 * Translate a single word to a token and append it to the token
650 	 * buffer. Every token consists of the address of the dictionary
651 	 * entry, the length of the word and the offset of the word from
652 	 * the start of the text buffer. Unknown words cause empty slots
653 	 * if the flag is set (such that the text can be scanned several
654 	 * times with different dictionaries); otherwise they are zero.
655 	 *
656 	 */
657 	void tokenise_text(zword text, zword length, zword from, zword parse, zword dct, bool flag);
658 
659 	/**
660 	 * Split an input line into words and translate the words to tokens.
661 	 */
662 	void tokenise_line(zword text, zword token, zword dct, bool flag);
663 
664 	/**
665 	 * Scan the vocabulary to complete the last word on the input line
666 	 * (similar to "tcsh" under Unix). The return value is
667 	 *
668 	 *    2 ==> completion is impossible
669 	 *    1 ==> completion is ambiguous
670 	 *    0 ==> completion is successful
671 	 *
672 	 * The function also returns a string in its second argument. In case
673 	 * of 2, the string is empty; in case of 1, the string is the longest
674 	 * extension of the last word on the input line that is common to all
675 	 * possible completions (for instance, if the last word on the input
676 	 * is "fo" and its only possible completions are "follow" and "folly"
677 	 * then the string is "ll"); in case of 0, the string is an extension
678 	 * to the last word that results in the only possible completion.
679 	 */
680 	int completion(const zchar *buffer, zchar *result);
681 
682 	 /**
683 	  * Convert a Unicode character to lowercase.
684 	  * Taken from Zip2000 by Kevin Bracey.
685 	  */
686 	zchar unicode_tolower(zchar c);
687 
688 	/**@}*/
689 
690 	/**
691 	 * \defgroup Window/V6 Opcode methods
692 	 * @{
693 	 */
694 
695 	/**
696 	 * Return the window number in zargs[0]. In V6 only, -3 refers to the
697 	 * current window.
698 	 */
699 	zword winarg0();
700 
701 	/**
702 	 * Return the (optional) window number in zargs[2]. -3 refers to the
703 	 * current window. This optional window number was only used by some
704 	 * V6 opcodes: set_cursor, set_margins, set_colour.
705 	 */
706 	zword winarg2();
707 
708 	 /**@}*/
709 protected:
710 	/**
711 	 * \defgroup General Opcode methods
712 	 * @{
713 	 */
714 
715 	/*
716 	 * Load and execute an extended opcode.
717 	 */
718 	void __extended__();
719 
720 	/*
721 	 * Exit game because an unknown opcode has been hit.
722 	 */
723 	void __illegal__();
724 
725 	/*
726 	 * Store the current _stack frame for later use with z_throw.
727 	 *
728 	 *	no zargs used
729 	 */
730 	void z_catch();
731 
732 	/**
733 	 * Go back to the given _stack frame and return the given value.
734 	 *
735 	 *	zargs[0] = value to return
736 	 *	zargs[1] = _stack frame
737 	 */
738 	void z_throw();
739 
740 	/*
741 	 * Call a subroutine and discard its result.
742 	 *
743 	 * 	zargs[0] = packed address of subroutine
744 	 *	zargs[1] = first argument (optional)
745 	 *	...
746 	 *	zargs[7] = seventh argument (optional)
747 	 */
748 	void z_call_n();
749 
750 	/**
751 	 * Call a subroutine and store its result.
752 	 *
753 	 * 	zargs[0] = packed address of subroutine
754 	 *	zargs[1] = first argument (optional)
755 	 *	...
756 	 *	zargs[7] = seventh argument (optional)
757 	 */
758 	void z_call_s();
759 
760 	/**
761 	 * Branch if subroutine was called with >= n arg's.
762 	 *
763 	 * 	zargs[0] = number of arguments
764 	 */
765 	void z_check_arg_count();
766 
767 	/**
768 	 * Jump unconditionally to the given address.
769 	 *
770 	 *	zargs[0] = PC relative address
771 	 */
772 	void z_jump();
773 
774 	/*
775 	 * No operation.
776 	 *
777 	 *	no zargs used
778 	 */
779 	void z_nop();
780 
781 	/*
782 	 * Stop game and exit interpreter.
783 	 *
784 	 *	no zargs used
785 	 */
786 	void z_quit();
787 
788 	/*
789 	 * Return from a subroutine with the given value.
790 	 *
791 	 *	zargs[0] = value to return
792 	 */
793 	void z_ret();
794 
795 	/*
796 	 * Return from a subroutine with a value popped off the stack.
797 	 *
798 	 *	no zargs used
799 	 */
800 	void z_ret_popped();
801 
802 	/*
803 	 * Return from a subroutine with false (0).
804 	 *
805 	 * 	no zargs used
806 	 */
807 	void z_rfalse();
808 
809 	/*
810 	 * Return from a subroutine with true (1).
811 	 *
812 	 * 	no zargs used
813 	 */
814 	void z_rtrue();
815 
816 	/**
817 	 * Store a random number or set the random number seed.
818 	 *
819 	 *	zargs[0] = range (positive) or seed value (negative)
820 	 */
821 	void z_random();
822 
823 	/**
824 	 * Load / play / stop / discard a sound effect.
825 	 *
826 	 *	zargs[0] = number of bleep (1 or 2) or sample
827 	 *	zargs[1] = operation to perform (samples only)
828 	 *	zargs[2] = repeats and volume (play sample only)
829 	 *	zargs[3] = end-of-sound routine (play sample only, optional)
830 	 *
831 	 * Note: Volumes range from 1 to 8, volume 255 is the default volume.
832 	 *	 Repeats are stored in the high byte, 255 is infinite loop.
833 	 *
834 	 */
835 	void z_sound_effect();
836 
837 	/**
838 	 * Branch if the story file is a legal copy
839 	 */
840 	void z_piracy();
841 
842 	/**
843 	 * Save the current Z-machine state for a future undo.
844 	 *
845 	 *	no zargs used
846 	 */
847 	void z_save_undo();
848 
849 	/**
850 	 * Restore a Z-machine state from memory.
851 	 *
852 	 *	no zargs used
853 	 */
854 	void z_restore_undo();
855 
856 	/**@}*/
857 
858 	/**
859 	 * \defgroup Input Opcode methods
860 	 * @{
861 	 */
862 
863 	 /**
864 	  * Add or remove a menu and branch if successful.
865 	  *
866 	  * 	zargs[0] = number of menu
867 	  *	zargs[1] = table of menu entries or 0 to remove menu
868 	  */
869 	void z_make_menu();
870 
871 	/**
872 	 * Read a line of input and (in V5+) store the terminating key.
873 	 *
874 	 *	zargs[0] = address of text buffer
875 	 *	zargs[1] = address of token buffer
876 	 *	zargs[2] = timeout in tenths of a second (optional)
877 	 *	zargs[3] = packed address of routine to be called on timeout
878 	 */
879 	void z_read();
880 
881 	/**
882 	 * Read and store a key.
883 	 *
884 	 *	zargs[0] = input device (must be 1)
885 	 *	zargs[1] = timeout in tenths of a second (optional)
886 	 *	zargs[2] = packed address of routine to be called on timeout
887 	 */
888 	void z_read_char();
889 
890 	/**
891 	 * z_read_mouse, write the current mouse status into a table.
892 	 *
893 	 *	zargs[0] = address of table
894 	 */
895 	void z_read_mouse();
896 
897 	/**@}*/
898 
899 	/**
900 	 * \defgroup Math Opcode methods
901 	 * @{
902 	 */
903 
904 	/**
905 	 * 16 bit addition.
906 	 *
907 	 *	zargs[0] = first value
908 	 *	zargs[1] = second value
909 	 */
910 	void z_add();
911 
912 	/**
913 	 * Bitwise AND operation.
914 	 *
915 	 *	zargs[0] = first value
916 	 *	zargs[1] = second value
917 	 */
918 	void z_and();
919 
920 	/**
921 	 * Arithmetic SHIFT operation.
922 	 *
923 	 *	zargs[0] = value
924 	 *	zargs[1] = #positions to shift left (positive) or right
925 	 */
926 	void z_art_shift();
927 
928 	/**
929 	 * Signed 16bit division.
930 	 *
931 	 *	zargs[0] = first value
932 	 *	zargs[1] = second value
933 	 */
934 	void z_div();
935 
936 	/**
937 	 * B ranch if the first value equals any of the following.
938 	 *
939 	 *	zargs[0] = first value
940 	 *	zargs[1] = second value (optional)
941 	 *	...
942 	 *	zargs[3] = fourth value (optional)
943 	 */
944 	void z_je();
945 
946 	/**
947 	 * Branch if the first value is greater than the second.
948 	 *
949 	 *	zargs[0] = first value
950 	 *	zargs[1] = second value
951 	 */
952 	void z_jg();
953 
954 	/**
955 	 * Branch if the first value is less than the second.
956 	 *
957 	 *	zargs[0] = first value
958 	 *	zargs[1] = second value
959 	 */
960 	void z_jl();
961 
962 	/**
963 	 * Branch if value is zero.
964 	 *
965 	 * 	zargs[0] = value
966 	 */
967 	void z_jz();
968 
969 	/**
970 	 * Logical SHIFT operation.
971 	 *
972 	 * 	zargs[0] = value
973 	 *	zargs[1] = #positions to shift left (positive) or right (negative)
974 	 */
975 	void z_log_shift();
976 
977 	/*
978 	 * Remainder after signed 16bit division.
979 	 *
980 	 * 	zargs[0] = first value
981 	 *	zargs[1] = second value
982 	 */
983 	void z_mod();
984 
985 	/**
986 	 * 16 bit multiplication.
987 	 *
988 	 * 	zargs[0] = first value
989 	 *	zargs[1] = second value
990 	 */
991 	void z_mul();
992 
993 	/**
994 	 * Bitwise NOT operation.
995 	 *
996 	 * 	zargs[0] = value
997 	 */
998 	void z_not();
999 
1000 	/**
1001 	 * Bitwise OR operation.
1002 	 *
1003 	 *	zargs[0] = first value
1004 	 *	zargs[1] = second value
1005 	 */
1006 	void z_or();
1007 
1008 	/**
1009 	 * 16 bit substraction.
1010 	 *
1011 	 *	zargs[0] = first value
1012 	 *	zargs[1] = second value
1013 	 */
1014 	void z_sub();
1015 
1016 	/**
1017 	 * Branch if all the flags of a bit mask are set in a value.
1018 	 *
1019 	 *	zargs[0] = value to be examined
1020 	 *	zargs[1] = bit mask
1021 	 */
1022 	void z_test();
1023 
1024 	/**@}*/
1025 
1026 	/**
1027 	 * \defgroup Object Opcode methods
1028 	 * @{
1029 	 */
1030 
1031 	/**
1032 	 * Branch if the first object is inside the second.
1033 	 *
1034 	 *        zargs[0] = first object
1035 	 *        zargs[1] = second object
1036 	 */
1037 	void z_jin();
1038 
1039 	/**
1040 	 * Store the child of an object.
1041 	 *
1042 	 *        zargs[0] = object
1043 	 */
1044 	void z_get_child();
1045 
1046 	/**
1047 	 * Store the number of the first or next property.
1048 	 *
1049 	 *        zargs[0] = object
1050 	 *        zargs[1] = address of current property (0 gets the first property)
1051 	 */
1052 	void z_get_next_prop();
1053 
1054 	/**
1055 	 * Store the parent of an object.
1056 	 *
1057 	 *        zargs[0] = object
1058 	 */
1059 	void z_get_parent();
1060 
1061 	/**
1062 	 * Store the value of an object property.
1063 	 *
1064 	 *        zargs[0] = object
1065 	 *        zargs[1] = number of property to be examined
1066 	 */
1067 	void z_get_prop();
1068 
1069 	/**
1070 	 * Store the address of an object property.
1071 	 *
1072 	 *        zargs[0] = object
1073 	 *        zargs[1] = number of property to be examined
1074 	 */
1075 	void z_get_prop_addr();
1076 
1077 	/**
1078 	 * Store the length of an object property.
1079 	 *
1080 	 *         zargs[0] = address of property to be examined
1081 	 */
1082 	void z_get_prop_len();
1083 
1084 	/**
1085 	 * Store the sibling of an object.
1086 	 *
1087 	 *        zargs[0] = object
1088 	 */
1089 	void z_get_sibling();
1090 
1091 	/**
1092 	 * Make an object the first child of another object.
1093 	 *
1094 	 *        zargs[0] = object to be moved
1095 	 *        zargs[1] = destination object
1096 	 */
1097 	void z_insert_obj();
1098 
1099 	/**
1100 	 * Set the value of an object property.
1101 	 *
1102 	 *        zargs[0] = object
1103 	 *        zargs[1] = number of property to set
1104 	 *        zargs[2] = value to set property to
1105 	 */
1106 	void z_put_prop();
1107 
1108 	/**
1109 	 * Unlink an object from its parent and siblings.
1110 	 *
1111 	 *        zargs[0] = object
1112 	 */
1113 	void z_remove_obj();
1114 
1115 	/**
1116 	 * Set an object attribute.
1117 	 *
1118 	 *        zargs[0] = object
1119 	 *        zargs[1] = number of attribute to set
1120 	 */
1121 	void z_set_attr();
1122 
1123 	/**
1124 	 * Branch if an object attribute is set.
1125 	 *
1126 	 *        zargs[0] = object
1127 	 *        zargs[1] = number of attribute to test
1128 	 */
1129 	void z_test_attr();
1130 
1131 	/**
1132 	 * Clear an object attribute.
1133 	 *
1134 	 *        zargs[0] = object
1135 	 *        zargs[1] = number of attribute to be cleared
1136 	 */
1137 	void z_clear_attr();
1138 
1139 	/**@}*/
1140 
1141 	/**
1142 	 * \defgroup Screen Opcode methods
1143 	 * @{
1144 	 */
1145 
1146 	/**
1147 	 * Turn text buffering on/off.
1148 	 *
1149 	 *		zargs[0] = new text buffering flag (0 or 1)
1150 	 */
1151 	void z_buffer_mode();
1152 
1153 	/**
1154 	 * Set the screen buffering mode.
1155 	 *
1156 	 *	zargs[0] = mode
1157 	 */
1158 	void z_buffer_screen();
1159 
1160 	/**
1161 	 * Erase the line starting at the cursor position.
1162 	 *
1163 	 *		zargs[0] = 1 + #units to erase (1 clears to the end of the line)
1164 	 */
1165 	void z_erase_line();
1166 
1167 	/**
1168 	 * Erase a window or the screen to background colour.
1169 	 *
1170 	 *		zargs[0] = window (-3 current, -2 screen, -1 screen & unsplit)
1171 	 */
1172 	void z_erase_window();
1173 
1174 	/**
1175 	 * Write the cursor coordinates into a table.
1176 	 *
1177 	 *		zargs[0] = address to write information to
1178 	 */
1179 	void z_get_cursor();
1180 
1181 	/**
1182 	 * Print ASCII text in a rectangular area.
1183 	 *
1184 	 *		zargs[0] = address of text to be printed
1185 	 *		zargs[1] = width of rectangular area
1186 	 *		zargs[2] = height of rectangular area (optional)
1187 	 *		zargs[3] = number of char's to skip between lines (optional)
1188 	 */
1189 	void z_print_table();
1190 
1191 	/**
1192 	 * Set the foreground and background colours
1193 	 * to specific RGB colour values.
1194 	 *
1195 	 *	zargs[0] = foreground colour
1196 	 *	zargs[1] = background colour
1197 	 *	zargs[2] = window (-3 is the current one, optional)
1198 	 */
1199 	void z_set_true_colour();
1200 
1201 	/**
1202 	 * Set the foreground and background colours.
1203 	 *
1204 	 *		zargs[0] = foreground colour
1205 	 *		zargs[1] = background colour
1206 	 *		zargs[2] = window (-3 is the current one, optional)
1207 	 */
1208 	void z_set_colour();
1209 
1210 	/**
1211 	 * Set the font for text output and store the previous font.
1212 	 *
1213 	 *		 zargs[0] = number of font or 0 to keep current font
1214 	 */
1215 	void z_set_font();
1216 
1217 	/**
1218 	 * Set the cursor position or turn the cursor on/off.
1219 	 *
1220 	 *		zargs[0] = y-coordinate or -2/-1 for cursor on/off
1221 	 *		zargs[1] = x-coordinate
1222 	 *		zargs[2] = window (-3 is the current one, optional)
1223 	 */
1224 	void z_set_cursor();
1225 
1226 	/**
1227 	 * z_set_text_style, set the style for text output.
1228 	 *
1229 	 *		 zargs[0] = style flags to set or 0 to reset text style
1230 	 */
1231 	void z_set_text_style();
1232 
1233 	/**
1234 	 * Select the current window.
1235 	 *
1236 	 *		zargs[0] = window to be selected (-3 is the current one)
1237 	 */
1238 	void z_set_window();
1239 
1240 	/**
1241 	 * Display the status line for V1 to V3 games.
1242 	 *
1243 	 *		no zargs used
1244 	 */
1245 	void pad_status_line(int column);
1246 
1247 	/**
1248 	 * Display the status line for V1 to V3 games.
1249 	 *
1250 	 *		no zargs used
1251 	 */
1252 	void z_show_status();
1253 
1254 	/**
1255 	 * Split the screen into an upper (1) and lower (0) window.
1256 	 *
1257 	 *		zargs[0] = height of upper window in screen units (V6) or #lines
1258 	 */
1259 	void z_split_window();
1260 
1261 	/**@}*/
1262 
1263 	/**
1264 	 * \defgroup Stream Opcode methods
1265 	 * @{
1266 	 */
1267 
1268 	/**
1269 	 * Select an input stream.
1270 	 *
1271 	 *	zargs[0] = input stream to be selected
1272 	 */
1273 	void z_input_stream();
1274 
1275 	/**
1276 	 * Open or close an output stream.
1277 	 *
1278 	 *	zargs[0] = stream to open (positive) or close (negative)
1279 	 *	zargs[1] = address to redirect output to (stream 3 only)
1280 	 *	zargs[2] = width of redirected output (stream 3 only, optional)
1281 	 */
1282 	void z_output_stream();
1283 
1284 	/**
1285 	 * Re-load dynamic area, clear the stack and set the PC.
1286 	 *
1287 	 * 	no zargs used
1288 	 */
1289 	void z_restart();
1290 
1291 	/**
1292 	 * Save [a part of] the Z-machine state to disk.
1293 	 *
1294 	 *	zargs[0] = address of memory area to save (optional)
1295 	 *	zargs[1] = number of bytes to save
1296 	 *	zargs[2] = address of suggested file name
1297 	 */
1298 	void z_save();
1299 
1300 	/**
1301 	 * Restore [a part of] a Z-machine state from disk
1302 	 *
1303 	 *	zargs[0] = address of area to restore (optional)
1304 	 *	zargs[1] = number of bytes to restore
1305 	 *	zargs[2] = address of suggested file name
1306 	 */
1307 	void z_restore();
1308 
1309 	/**
1310 	 * Check the story file integrity.
1311 	 *
1312 	 *	no zargs used
1313 	 */
1314 	void z_verify();
1315 
1316 	/**@}*/
1317 
1318 	/**
1319 	 * \defgroup Table Opcode methods
1320 	 * @{
1321 	 */
1322 
1323 	/**
1324 	 * Copy a table or fill it with zeroes.
1325 	 *
1326 	 *	zargs[0] = address of table
1327 	 * 	zargs[1] = destination address or 0 for fill
1328 	 *	zargs[2] = size of table
1329 	 *
1330 	 * Note: Copying is safe even when source and destination overlap; but
1331 	 *       if zargs[1] is negative the table _must_ be copied forwards.
1332 	 */
1333 	void z_copy_table();
1334 
1335 	/**
1336 	 * Store a value from a table of bytes.
1337 	 *
1338 	 *	zargs[0] = address of table
1339 	 *	zargs[1] = index of table entry to store
1340 	 */
1341 	void z_loadb();
1342 
1343 	/**
1344 	 * Store a value from a table of words.
1345 	 *
1346 	 *	zargs[0] = address of table
1347 	 *	zargs[1] = index of table entry to store
1348 	 */
1349 	void z_loadw();
1350 
1351 	/**
1352 	 * Find and store the address of a target within a table.
1353 	 *
1354 	 *	zargs[0] = target value to be searched for
1355 	 *	zargs[1] = address of table
1356 	 *	zargs[2] = number of table entries to check value against
1357 	 *	zargs[3] = type of table (optional, defaults to 0x82)
1358 	 *
1359 	 * Note: The table is a word array if bit 7 of zargs[3] is set; otherwise
1360 	 *       it's a byte array. The lower bits hold the address step.
1361 	 */
1362 	void z_scan_table();
1363 
1364 	/**
1365 	 * Write a byte into a table of bytes.
1366 	 *
1367 	 *	zargs[0] = address of table
1368 	 *	zargs[1] = index of table entry
1369 	 *	zargs[2] = value to be written
1370 	 */
1371 	void z_storeb();
1372 
1373 	/**
1374 	 * Write a word into a table of words.
1375 	 *
1376 	 *	zargs[0] = address of table
1377 	 *	zargs[1] = index of table entry
1378 	 *	zargs[2] = value to be written
1379 	 */
1380 	void z_storew();
1381 
1382 	/**@}*/
1383 
1384 	/**
1385 	 * \defgroup Text Opcode methods
1386 	 * @{
1387 	 */
1388 
1389 	/**
1390 	 * Test if a unicode character can be printed (bit 0) and read (bit 1).
1391 	 *
1392 	 * 	zargs[0] = Unicode
1393 	 */
1394 	void z_check_unicode();
1395 
1396 	/**
1397 	 * Encode a ZSCII string for use in a dictionary.
1398 	 *
1399 	 *	zargs[0] = address of text buffer
1400 	 *	zargs[1] = length of ASCII string
1401 	 *	zargs[2] = offset of ASCII string within the text buffer
1402 	 *	zargs[3] = address to store encoded text in
1403 	 *
1404 	 * This is a V5+ opcode and therefore the dictionary resolution must be
1405 	 * three 16bit words.
1406 	 */
1407 	void z_encode_text();
1408 
1409 	/**
1410 	 * Print a new line.
1411 	 *
1412 	 * 	no zargs used
1413 	 *
1414 	 */
1415 	void z_new_line();
1416 
1417 	/**
1418 	 * Print a string embedded in the instruction stream.
1419 	 *
1420 	 *	no zargs used
1421 	 */
1422 	void z_print();
1423 
1424 	/**
1425 	 * Print a string from the lower 64KB.
1426 	 *
1427 	 *	zargs[0] = address of string to print
1428 	 */
1429 	void z_print_addr();
1430 
1431 	/**
1432 	 * Print a single ZSCII character.
1433 	 *
1434 	 *	zargs[0] = ZSCII character to be printed
1435 	 */
1436 	void z_print_char();
1437 
1438 	/**
1439 	 * Print a formatted table.
1440 	 *
1441 	 *	zargs[0] = address of formatted table to be printed
1442 	 */
1443 	void z_print_form();
1444 
1445 	/**
1446 	 * Print a signed number.
1447 	 *
1448 	 * 	zargs[0] = number to print
1449 	 */
1450 	void z_print_num();
1451 
1452 	/**
1453 	 * Print an object description.
1454 	 *
1455 	 * 	zargs[0] = number of object to be printed
1456 	 */
1457 	void z_print_obj();
1458 
1459 	/**
1460 	 * Print the string at the given packed address.
1461 	 *
1462 	 * 	zargs[0] = packed address of string to be printed
1463 	 */
1464 	void z_print_paddr();
1465 
1466 	/*
1467 	 * Print the string at PC, print newline then return true.
1468 	 *
1469 	 * 	no zargs used
1470 	 */
1471 	void z_print_ret();
1472 
1473 	/**
1474 	 * Print unicode character
1475 	 *
1476 	 * 	zargs[0] = Unicode
1477 	 */
1478 	void z_print_unicode();
1479 
1480 	/**
1481 	 * Make a lexical analysis of a ZSCII string.
1482 	 *
1483 	 *	zargs[0] = address of string to analyze
1484 	 *	zargs[1] = address of token buffer
1485 	 *	zargs[2] = address of dictionary (optional)
1486 	 *	zargs[3] = set when unknown words cause empty slots (optional)
1487 	 */
1488 	void z_tokenise();
1489 
1490 	 /**@}*/
1491 
1492 	/**
1493 	 * \defgroup Variable Opcode methods
1494 	 * @{
1495 	 */
1496 
1497 	/**
1498 	 * Decrement a variable.
1499 	 *
1500 	 * 	zargs[0] = variable to decrement
1501 	 */
1502 	void z_dec();
1503 
1504 	/**
1505 	 * Decrement a variable and branch if now less than value.
1506 	 *
1507 	 * 	zargs[0] = variable to decrement
1508 	 * 	zargs[1] = value to check variable against
1509 	 */
1510 	void z_dec_chk();
1511 
1512 	/**
1513 	 * Increment a variable.
1514 	 *
1515 	 * 	zargs[0] = variable to increment
1516 	 */
1517 	void z_inc();
1518 
1519 	/**
1520 	 * Increment a variable and branch if now greater than value.
1521 	 *
1522 	 * 	zargs[0] = variable to increment
1523 	 * 	zargs[1] = value to check variable against
1524 	 */
1525 	void z_inc_chk();
1526 
1527 	/**
1528 	 * Store the value of a variable.
1529 	 *
1530 	 *	zargs[0] = variable to store
1531 	 */
1532 	void z_load();
1533 
1534 	/**
1535 	 * Pop a value off the game stack and discard it.
1536 	 *
1537 	 *	no zargs used
1538 	 */
1539 	void z_pop();
1540 
1541 	/**
1542 	 * Pop n values off the game or user stack and discard them.
1543 	 *
1544 	 *	zargs[0] = number of values to discard
1545 	 *	zargs[1] = address of user stack (optional)
1546 	 */
1547 	void z_pop_stack();
1548 
1549 	/**
1550 	 * Pop a value off...
1551 	 *
1552 	 * a) ...the game or a user stack and store it (V6)
1553 	 *
1554 	 *	zargs[0] = address of user stack (optional)
1555 	 *
1556 	 * b) ...the game stack and write it to a variable (other than V6)
1557 	 *
1558 	 *	zargs[0] = variable to write value to
1559 	 */
1560 	void z_pull();
1561 
1562 	/**
1563 	 * Push a value onto the game stack.
1564 	 *
1565 	 *	zargs[0] = value to push onto the stack
1566 	 */
1567 	void z_push();
1568 
1569 	/**
1570 	 * Push a value onto a user stack then branch if successful.
1571 	 *
1572 	 *	zargs[0] = value to push onto the stack
1573 	 *	zargs[1] = address of user stack
1574 	 */
1575 	void z_push_stack();
1576 
1577 	/**
1578 	 * Write a value to a variable.
1579 	 *
1580 	 * 	zargs[0] = variable to be written to
1581 	 *      zargs[1] = value to write
1582 	 */
1583 	void z_store();
1584 
1585 	/**@}*/
1586 
1587 	/**
1588 	 * \defgroup Window/V6 Opcode methods
1589 	 * @{
1590 	 */
1591 
1592 	/**
1593 	 * z_draw_picture, draw a picture.
1594 	 *
1595 	 *	zargs[0] = number of picture to draw
1596 	 *	zargs[1] = y-coordinate of top left corner
1597 	 *	zargs[2] = x-coordinate of top left corner
1598 	 */
1599 	void z_draw_picture();
1600 
1601 	/**
1602 	 * Get information on a picture or the graphics file.
1603 	 *
1604 	 *	zargs[0] = number of picture or 0 for the graphics file
1605 	 *	zargs[1] = address to write information to
1606 	 */
1607 	void z_picture_data();
1608 
1609 	/**
1610 	 * Erase a picture with background colour.
1611 	 *
1612 	 *	zargs[0] = number of picture to erase
1613 	 *	zargs[1] = y-coordinate of top left corner (optional)
1614 	 *	zargs[2] = x-coordinate of top left corner (optional)
1615 	 */
1616 	void z_erase_picture();
1617 
1618 	/**
1619 	 * Set the left and right margins of a window.
1620 	 *
1621 	 *	zargs[0] = left margin in pixels
1622 	 *	zargs[1] = right margin in pixels
1623 	 *	zargs[2] = window (-3 is the current one, optional)
1624 	 */
1625 	void z_set_margins();
1626 
1627 
1628 	/**
1629 	 * Place a window on the screen.
1630 	 *
1631 	 *	zargs[0] = window (-3 is the current one)
1632 	 *	zargs[1] = y-coordinate
1633 	 *	zargs[2] = x-coordinate
1634 	 *
1635 	 */
1636 	void z_move_window();
1637 
1638 	/**
1639 	 * Change the width and height of a window.
1640 	 *
1641 	 *	zargs[0] = window (-3 is the current one)
1642 	 *	zargs[1] = new height in screen units
1643 	 *	zargs[2] = new width in screen units
1644 	 */
1645 	void z_window_size();
1646 
1647 	/**
1648 	 * Set / clear / toggle window attributes.
1649 	 *
1650 	 *	zargs[0] = window (-3 is the current one)
1651 	 *	zargs[1] = window attribute flags
1652 	 *	zargs[2] = operation to perform (optional, defaults to 0)
1653 	 */
1654 	void z_window_style();
1655 
1656 	/**
1657 	 * Store the value of a window property.
1658 	 *
1659 	 *	zargs[0] = window (-3 is the current one)
1660 	 *	zargs[1] = number of window property to be stored
1661 	 */
1662 	void z_get_wind_prop();
1663 
1664 	/**
1665 	 * Set the value of a window property.
1666 	 *
1667 	 *	zargs[0] = window (-3 is the current one)
1668 	 *	zargs[1] = number of window property to set
1669 	 *	zargs[2] = value to set window property to
1670 	 */
1671 	void z_put_wind_prop();
1672 
1673 	/**
1674 	 * Scroll a window up or down.
1675 	 *
1676 	 *	zargs[0] = window (-3 is the current one)
1677 	 *	zargs[1] = #screen units to scroll up (positive) or down (negative)
1678 	 */
1679 	void z_scroll_window();
1680 
1681 	/**
1682 	 * Select a window as mouse window.
1683 	 *
1684 	 *	zargs[0] = window number (-3 is the current) or -1 for the screen
1685 	 */
1686 	void z_mouse_window();
1687 
1688 	/**
1689 	 * Prepare a group of pictures for faster display.
1690 	 *
1691 	 *	zargs[0] = address of table holding the picture numbers
1692 	 */
1693 	void z_picture_table();
1694 
1695 	 /**@}*/
1696 public:
1697 	/**
1698 	 * Constructor
1699 	 */
1700 	Processor(OSystem *syst, const GlkGameDescription &gameDesc);
~Processor()1701 	virtual ~Processor() {}
1702 
1703 	/**
1704 	 * Initialization
1705 	 */
1706 	void initialize();
1707 
1708 	/**
1709 	 * Z-code interpreter main loop
1710 	 */
1711 	void interpret();
1712 
1713 	/**
1714 	 * \defgroup Memory access methods
1715 	 * @{
1716 	 */
1717 
1718 	/**
1719 	 * Square brackets operator
1720 	 */
1721 	zbyte &operator[](uint addr) { return zmp[addr]; }
1722 
1723 	/**
1724 	 * Read a code byte
1725 	 */
codeByte()1726 	zbyte codeByte() { return *pcp++; }
1727 
1728 	/**
1729 	 * Read a code word
1730 	 */
codeWord()1731 	zword codeWord() {
1732 		zword v = READ_BE_UINT16(pcp);
1733 		pcp += 2;
1734 		return v;
1735 	}
1736 
1737 	/**
1738 	 * Return a code word at a given address
1739 	 */
codeWordIdx(uint addr)1740 	zword codeWordIdx(uint addr) const {
1741 		return READ_BE_UINT16(pcp + addr);
1742 	}
1743 
1744 	/**
1745 	 * Return the current program execution offset
1746 	 */
getPC()1747 	uint getPC() const {
1748 		assert(pcp);
1749 		return pcp - zmp;
1750 	}
1751 
1752 	/**
1753 	 * Set the program execution offset
1754 	 */
setPC(uint addr)1755 	void setPC(uint addr) { pcp = zmp + addr; }
1756 
1757 	 /**@}*/
1758 };
1759 
1760 } // End of namespace Frotz
1761 } // End of namespace Glk
1762 
1763 #endif
1764