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